HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GA_IntrinsicMacros.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GA_IntrinsicMacros.h ( GA Library, C++)
7  *
8  * COMMENTS:
9  */
10 
11 #ifndef __GA_IntrinsicMacros__
12 #define __GA_IntrinsicMacros__
13 
14 #include <GA/GA_IntrinsicDef.h>
15 #include <GA/GA_IntrinsicEval.h>
16 #include <UT/UT_Assert.h>
17 #include <UT/UT_StringArray.h>
18 #include <UT/UT_StackAlloc.h>
19 #include <stdio.h>
20 
21 ///
22 /// The intrinsic macros help declaring intrinsic attributes for an object
23 /// (i.e. a primitive).
24 /// Typically, you'll have code like @code
25 /// enum {
26 /// ga_INTRINISIC_VAR1,
27 /// ga_INTRINISIC_VAR2,
28 /// ga_NUM_INTRINSICS
29 /// }
30 /// GA_START_INTRINSIC_DEF(ClassName, ga_NUM_INTRINSICS)
31 /// GA_INTRINSIC_I(ClassName, ga_INTRINSIC_VAR1, "name1",
32 /// EvaluationCallback)
33 /// GA_INTRINSIC_VARYING_F(ClassName, ga_INTRINISIC_VAR2, "name2",
34 /// TupleSizeMethod,
35 /// EvaluationCallback)
36 /// GA_END_INTRINSIC_DEF(ClassName, BaseClassName)
37 /// @endcode
38 ///
39 /// There are several ways to declare intrinsic access methods:
40 ///
41 /// GA_INTRINSIC_I(ClassName, Enum, Name, Callback)
42 /// - Tuple size is fixed at 1
43 /// - Callback returns value:
44 /// static exint callback(const ClassName *obj);
45 /// static fpreal callback(const ClassName *obj);
46 /// static const char *callback(const ClassName *obj);
47 ///
48 /// GA_INTRINSIC_CONST_I(ClassName, Enum, Name, Value)
49 /// - Tuple size is fixed at 1
50 /// - int/float/(const char *) Value is specified
51 ///
52 /// GA_INTRINSIC_METHOD_I(ClassName, Enum, Name, MethodName)
53 /// - Tuple size is fixed at 1
54 /// - MethodName specifies a public method on ClassName which returns the
55 /// value.
56 /// exint ClassName::MethodName() const;
57 /// fpreal ClassName::MethodName() const;
58 /// const char *ClassName::MethodName() const;
59 ///
60 /// GA_INTRINSIC_TUPLE_I(ClassName, Enum, Name, TUPLE_SIZE, Callback)
61 /// - TUPLE_SIZE is a constant value
62 /// - Callback fills value (returning number of items set):
63 /// static int callback(const ClassName *obj, int64 *v, GA_Size sz);
64 /// static int callback(const ClassName *obj, fpreal64 *v, GA_Size sz);
65 /// static void callback(const ClassName *obj, UT_StringArray &v);
66 ///
67 /// GA_INTRINSIC_TUPLE_METHOD_I(ClassName, Enum, Name, TUPLE_SIZE, MethodName)
68 /// - TUPLE_SIZE is a constant value
69 /// - MethodName is a public method on ClassName which fills the value,
70 /// returning the number of items set:
71 /// int ClassName::MethodName(int64 *v, GA_Size sz) const;
72 /// int ClassName::MethodName(fpreal64 *v, GA_Size sz) const;
73 /// void ClassName::MethodName(UT_StringArray &v, GA_Size sz) const;
74 ///
75 /// GA_INTRINSIC_ARRAY_I(ClassName, Enum, Name, ArrayType, MethodName)
76 /// - ArrayType specifies an array which has:
77 /// - entries() const: Return number of elements in the array
78 /// - operator()(exint i) const: Returning the element of the array
79 /// - MethodName is a public method on ClassName which returns the a const
80 /// reference to an ArrayType object.
81 /// const ArrayType &ClassName::MethodName() const
82 ///
83 /// GA_INTRINSIC_VARYING_I(ClassName, Enum, Name, TupleSizeCallback, Callback)
84 /// - TupleSizeCallback is a function returning the tuple size
85 /// static int tuplesizecallback(const ClassName *obj)
86 /// - Callback fills value, returning number of items set:
87 /// static int callback(const ClassName *obj, int64 *v, GA_Size sz);
88 /// static int callback(const ClassName *obj, fpreal64 *v, GA_Size sz);
89 /// static int callback(const ClassName *obj, UT_StringArray &v);
90 ///
91 /// For setting values, there are similar macros. The tuple size and name are
92 /// usually defined by the evaluation macros. If there is no "get" method, you
93 /// can still declare the intrinsic using:
94 /// GA_INTRINSIC_DEF_I(Enum, Name, TupleSize)
95 /// GA_INTRINSIC_DEF_VARYING_I(Enum, Name, TupleSizeFunc)
96 ///
97 /// GA_INTRINSIC_SET_I(ClassName, Enum, Callback)
98 /// - Callback specifies a static function which sets the value, returning
99 /// false if unable to set (i.e. invalid value). The function can take a
100 /// 32/64 bit value.
101 /// static bool set(ClassName *o, exint v);
102 /// static bool set(ClassName *o, fpreal v);
103 /// static bool set(ClassName *o, const char *v);
104 ///
105 /// GA_INTRINSIC_SET_METHOD_I(ClassName, Enum, MethodName)
106 /// - MethodName specifies a public method on ClassName which sets the
107 /// value. The method can take 32/64 bit values
108 /// bool ClassName::MethodName(exint value);
109 /// bool ClassName::MethodName(fpreal value);
110 ///
111 /// GA_INTRINSIC_SET_TUPLE_I(ClassName, Enum, Callback)
112 /// - Callback specifies a static function which sets the value, returning
113 /// the number of values set.
114 /// static int set(ClassName *o, const int64 *v, int tuple_size);
115 /// static int set(ClassName *o, const fpreal64 *v, int tuple_size);
116 /// static int set(ClassName *o, const UT_StringArray &v);
117 ///
118 /// GA_INTRINSIC_SET_TUPLE_METHOD_I(ClassName, Enum, Callback)
119 /// - Callback specifies a static function which sets the value, returning
120 /// the number of values set.
121 /// int ClassName::set(const int64 *v, int tuple_size);
122 /// int ClassName::set(const fpreal64 *v, int tuple_size);
123 /// int ClassName::set(const UT_StringArray &v);
124 
125 #define GA_START_INTRINSIC_DEF(CLASS, NUM_INTRINSICS) \
126  namespace \
127 { \
128  class _ga_intrinsicEvaluator##CLASS \
129  { \
130  public: \
131  typedef GA_Size (*cbTupleSize)(const CLASS *obj); \
132  typedef GA_Size (*cbEvalI)(const CLASS *obj, int64 *v, GA_Size size); \
133  typedef GA_Size (*cbEvalF)(const CLASS *obj, fpreal64 *v, GA_Size size); \
134  typedef GA_Size (*cbEvalS)(const CLASS *obj, UT_String &s); \
135  typedef GA_Size (*cbEvalSA)(const CLASS *obj, UT_StringArray &s); \
136  typedef GA_Size (*cbEvalD)(const CLASS *obj, UT_OptionsHolder &s); \
137  typedef GA_Size (*cbEvalDA)(const CLASS *obj, UT_Array<UT_OptionsHolder> &s); \
138  typedef GA_Size (*cbSetI)(CLASS *obj, const int64 *v, GA_Size size); \
139  typedef GA_Size (*cbSetF)(CLASS *obj, const fpreal64 *v, GA_Size size); \
140  typedef GA_Size (*cbSetS)(CLASS *obj, const char **v, GA_Size size); \
141  typedef GA_Size (*cbSetSA)(CLASS *obj, const UT_StringArray &v); \
142  typedef GA_Size (*cbSetD)(CLASS *obj, const UT_OptionsHolder *v, GA_Size size); \
143  typedef GA_Size (*cbSetDA)(CLASS *obj, const UT_Array<UT_OptionsHolder> &v); \
144  static GA_Size failTS(const CLASS *) { return 0; } \
145  static GA_Size failI(const CLASS *, int64 *, GA_Size) { UT_ASSERT(0); return 0; } \
146  static GA_Size failF(const CLASS *, fpreal64 *, GA_Size) { UT_ASSERT(0); return 0; } \
147  static GA_Size failS(const CLASS *, UT_String &) { UT_ASSERT(0); return 0; } \
148  static GA_Size failSA(const CLASS *, UT_StringArray &) { UT_ASSERT(0); return 0; } \
149  static GA_Size failD(const CLASS *, UT_OptionsHolder &) { UT_ASSERT(0); return 0; } \
150  static GA_Size failDA(const CLASS *, UT_Array<UT_OptionsHolder> &) { UT_ASSERT(0); return 0; } \
151  static GA_Size failI(CLASS *, const int64 *, GA_Size) { UT_ASSERT(0); return 0; } \
152  static GA_Size failF(CLASS *, const fpreal64 *, GA_Size) { UT_ASSERT(0); return 0; } \
153  static GA_Size failS(CLASS *, const char **, GA_Size) { UT_ASSERT(0); return 0; } \
154  static GA_Size failSA(CLASS *, const UT_StringArray &) { UT_ASSERT(0); return 0; } \
155  static GA_Size failD(CLASS *, const UT_OptionsHolder *, GA_Size) { UT_ASSERT(0); return 0; } \
156  static GA_Size failDA(CLASS *, const UT_Array<UT_OptionsHolder> &) { UT_ASSERT(0); return 0; } \
157  class Eval \
158  { \
159  public: \
160  Eval() \
161  : myId(-1) \
162  , myName(NULL) \
163  , myOptions(NULL) \
164  , myStore(GA_STORECLASS_INVALID) \
165  , myTupleSizeCB(failTS) \
166  , myTupleSize(-1) \
167  , myI(failI) \
168  , myF(failF) \
169  , myS(failS) \
170  , mySA(failSA) \
171  , myD(failD) \
172  , myDA(failDA) \
173  , mySetI(failI) \
174  , mySetF(failF) \
175  , mySetSS(failS) \
176  , mySetSA(failSA) \
177  , mySetDS(failD) \
178  , mySetDA(failDA) \
179  , myReadOnly(true) \
180  , myCollapseSingletons(true) \
181  { \
182  } \
183  GA_Size getTupleSize(const CLASS *o) const \
184  { \
185  if (myTupleSize > 0) return myTupleSize; \
186  return myTupleSizeCB(o); \
187  } \
188  void dump() { \
189  fprintf(stderr, "Intrinsic[%d] := {\n", myId); \
190  fprintf(stderr, " 'name' : '%s'\n", myName); \
191  fprintf(stderr, " 'tuple' : %d\n", (int)myTupleSize); \
192  fprintf(stderr, " 'storage' : %s\n", GAstorageClass(myStore));\
193  fprintf(stderr, " 'ro' : %d\n", myReadOnly); \
194  fprintf(stderr, " 'tuple()' : %p\n", myTupleSizeCB); \
195  fprintf(stderr, " 'options' : %p\n", myOptions); \
196  fprintf(stderr, " 'I()' : %p\n", myI); \
197  fprintf(stderr, " 'F()' : %p\n", myF); \
198  fprintf(stderr, " 'S()' : %p\n", myS); \
199  fprintf(stderr, " 'SA()' : %p\n", mySA); \
200  fprintf(stderr, " 'D()' : %p\n", myD); \
201  fprintf(stderr, " 'DA()' : %p\n", myDA); \
202  fprintf(stderr, " 'setI()' : %p\n", mySetI); \
203  fprintf(stderr, " 'setF()' : %p\n", mySetF); \
204  fprintf(stderr, " 'setSS()' : %p\n", mySetSS); \
205  fprintf(stderr, " 'setSA()' : %p\n", mySetSA); \
206  fprintf(stderr, " 'setDS()' : %p\n", mySetDS); \
207  fprintf(stderr, " 'setDA()' : %p\n", mySetDA); \
208  } \
209  bool valid(int index) const \
210  { \
211  if (myName && myId >= 0 && myStore != GA_STORECLASS_INVALID \
212  && (myTupleSize > 0 || myTupleSizeCB) \
213  && (myI || myF || myS || mySA)) \
214  return true; \
215  fprintf(stderr, "Warning: missing intrinsic for %s[%d]\n", \
216 #CLASS, index); \
217  return false; \
218  } \
219  cbTupleSize myTupleSizeCB; \
220  cbEvalI myI; \
221  cbEvalF myF; \
222  cbEvalS myS; \
223  cbEvalSA mySA; \
224  cbEvalD myD; \
225  cbEvalDA myDA; \
226  cbSetI mySetI; \
227  cbSetF mySetF; \
228  cbSetS mySetSS; \
229  cbSetSA mySetSA; \
230  cbSetD mySetDS; \
231  cbSetDA mySetDA; \
232  const char *myName; \
233  const UT_Options *myOptions; \
234  GA_Size myTupleSize; \
235  int myId; \
236  GA_StorageClass myStore; \
237  bool myReadOnly; \
238  bool myCollapseSingletons; \
239  }; \
240  Eval myEval[NUM_INTRINSICS]; \
241  int entries() const { return NUM_INTRINSICS; } \
242  bool valid(int i) const { return myEval[i].valid(i); } \
243  GA_Size getTupleSize(int i, const CLASS *o) const \
244  { return myEval[i].getTupleSize(o); } \
245  GA_Size evalI(int i, const CLASS *o, int64 *v, GA_Size n) const \
246  { return myEval[i].myI(o, v, n); } \
247  GA_Size evalF(int i, const CLASS *o, fpreal64 *v, GA_Size n) const \
248  { return myEval[i].myF(o, v, n); } \
249  GA_Size evalS(int i, const CLASS *o, UT_String &v) const \
250  { return myEval[i].myS(o, v); } \
251  GA_Size evalSA(int i, const CLASS *o, UT_StringArray &v) const \
252  { return myEval[i].mySA(o, v); } \
253  GA_Size evalD(int i, const CLASS *o, UT_OptionsHolder &v) const \
254  { return myEval[i].myD(o, v); } \
255  GA_Size evalDA(int i, const CLASS *o, UT_Array<UT_OptionsHolder> &v) const \
256  { return myEval[i].myDA(o, v); } \
257  GA_Size setI(int i, CLASS *o, const int64 *v, GA_Size n) const \
258  { return myEval[i].mySetI(o, v, n); } \
259  GA_Size setF(int i, CLASS *o, const fpreal64 *v, GA_Size n) const \
260  { return myEval[i].mySetF(o, v, n); } \
261  GA_Size setSS(int i, CLASS *o, const char **v, GA_Size n) const \
262  { return myEval[i].mySetSS(o, v, n); } \
263  GA_Size setSA(int i, CLASS *o, const UT_StringArray &v) const \
264  { return myEval[i].mySetSA(o, v); } \
265  GA_Size setDS(int i, CLASS *o, const UT_OptionsHolder *v, GA_Size n) const \
266  { return myEval[i].mySetDS(o, v, n); } \
267  GA_Size setDA(int i, CLASS *o, const UT_Array<UT_OptionsHolder> &v) const \
268  { return myEval[i].mySetDA(o, v); } \
269  GA_StorageClass getStorageClass(int i) const \
270  { return myEval[i].myStore; } \
271  const char *getName(int i) const { return myEval[i].myName; } \
272  int getId(int i) const { return myEval[i].myId; } \
273  bool getReadOnly(int i) const { return myEval[i].myReadOnly; } \
274  bool getCollapseSingletons(int i) const \
275  { return myEval[i].myCollapseSingletons; } \
276  const UT_Options *getOptions(int i) const \
277  { return myEval[i].myOptions; } \
278  _ga_intrinsicEvaluator##CLASS() {
279 
280 #define GA_END_INTRINSIC_DEF(CLASS, BASECLASS) \
281  } \
282  }; \
283  static GA_IntrinsicDef _theIntrinsics##CLASS; \
284  static _ga_intrinsicEvaluator##CLASS _theEval##CLASS; \
285 } \
286  GA_IntrinsicManager::Registrar \
287  CLASS::registerIntrinsics(GA_PrimitiveDefinition &defn) \
288 { \
289  GA_IntrinsicManager::Registrar r(BASECLASS::registerIntrinsics(defn)); \
290  using Collapse = GA_IntrinsicManager::CollapseSingletons; \
291  if (r.start(_theIntrinsics##CLASS)) \
292  { \
293  for (int i = 0; i < _theEval##CLASS.entries(); ++i) \
294  { \
295  UT_ASSERT(_theEval##CLASS.getName(i)); \
296  if (_theEval##CLASS.valid(i)) \
297  { \
298  r.addAttribute(_theEval##CLASS.getStorageClass(i), \
299  _theEval##CLASS.getName(i), \
300  _theEval##CLASS.getId(i), \
301  _theEval##CLASS.getReadOnly(i), \
302  _theEval##CLASS.getCollapseSingletons(i) ? \
303  Collapse::YES : Collapse::NO, \
304  _theEval##CLASS.getOptions(i)); \
305  } \
306  } \
307  } \
308  return r; \
309 } \
310  GA_Size \
311  CLASS::localIntrinsicTupleSize(const GA_IntrinsicEval &eval) const \
312 { \
313  int id = eval.getUserId(_theIntrinsics##CLASS); \
314  if (id >= 0 && id < _theEval##CLASS.entries()) \
315  return _theEval##CLASS.getTupleSize(id, this); \
316  return BASECLASS::localIntrinsicTupleSize(eval); \
317 } \
318  GA_Size \
319  CLASS::localGetIntrinsicI(const GA_IntrinsicEval &eval, \
320  int64 *v, GA_Size size) const \
321 { \
322  int id = eval.getUserId(_theIntrinsics##CLASS); \
323  if (id >= 0 && id < _theEval##CLASS.entries()) \
324  return _theEval##CLASS.evalI(id, this, v, size); \
325  return BASECLASS::localGetIntrinsicI(eval, v, size); \
326 } \
327  GA_Size \
328  CLASS::localGetIntrinsicF(const GA_IntrinsicEval &eval, \
329  fpreal64 *v, GA_Size size) const \
330 { \
331  int id = eval.getUserId(_theIntrinsics##CLASS); \
332  if (id >= 0 && id < _theEval##CLASS.entries()) \
333  return _theEval##CLASS.evalF(id, this, v, size); \
334  return BASECLASS::localGetIntrinsicF(eval, v, size); \
335 } \
336  GA_Size \
337  CLASS::localGetIntrinsicS(const GA_IntrinsicEval &eval, \
338  UT_String &v) const \
339 { \
340  int id = eval.getUserId(_theIntrinsics##CLASS); \
341  if (id >= 0 && id < _theEval##CLASS.entries()) \
342  return _theEval##CLASS.evalS(id, this, v); \
343  return BASECLASS::localGetIntrinsicS(eval, v); \
344 } \
345  GA_Size \
346  CLASS::localGetIntrinsicSA(const GA_IntrinsicEval &eval, \
347  UT_StringArray &v) const \
348 { \
349  int id = eval.getUserId(_theIntrinsics##CLASS); \
350  if (id >= 0 && id < _theEval##CLASS.entries()) \
351  return _theEval##CLASS.evalSA(id, this, v); \
352  return BASECLASS::localGetIntrinsicSA(eval, v); \
353 } \
354  GA_Size \
355  CLASS::localGetIntrinsicD(const GA_IntrinsicEval &eval, \
356  UT_OptionsHolder &v) const \
357 { \
358  int id = eval.getUserId(_theIntrinsics##CLASS); \
359  if (id >= 0 && id < _theEval##CLASS.entries()) \
360  return _theEval##CLASS.evalD(id, this, v); \
361  return BASECLASS::localGetIntrinsicD(eval, v); \
362 } \
363  GA_Size \
364  CLASS::localGetIntrinsicDA(const GA_IntrinsicEval &eval, \
365  UT_Array<UT_OptionsHolder> &v) const \
366 { \
367  int id = eval.getUserId(_theIntrinsics##CLASS); \
368  if (id >= 0 && id < _theEval##CLASS.entries()) \
369  return _theEval##CLASS.evalDA(id, this, v); \
370  return BASECLASS::localGetIntrinsicDA(eval, v); \
371 } \
372  GA_Size \
373  CLASS::localSetIntrinsicI(const GA_IntrinsicEval &eval, \
374  const int64 *v, GA_Size size) \
375 { \
376  int id = eval.getUserId(_theIntrinsics##CLASS); \
377  if (id >= 0 && id < _theEval##CLASS.entries()) \
378  return _theEval##CLASS.setI(id, this, v, size); \
379  return BASECLASS::localSetIntrinsicI(eval, v, size); \
380 } \
381  GA_Size \
382  CLASS::localSetIntrinsicF(const GA_IntrinsicEval &eval, \
383  const fpreal64 *v, GA_Size size) \
384 { \
385  int id = eval.getUserId(_theIntrinsics##CLASS); \
386  if (id >= 0 && id < _theEval##CLASS.entries()) \
387  return _theEval##CLASS.setF(id, this, v, size); \
388  return BASECLASS::localSetIntrinsicF(eval, v, size); \
389 } \
390  GA_Size \
391  CLASS::localSetIntrinsicSS(const GA_IntrinsicEval &eval, \
392  const char **v, GA_Size size) \
393 { \
394  int id = eval.getUserId(_theIntrinsics##CLASS); \
395  if (id >= 0 && id < _theEval##CLASS.entries()) \
396  return _theEval##CLASS.setSS(id, this, v, size); \
397  return BASECLASS::localSetIntrinsicSS(eval, v, size); \
398 } \
399  GA_Size \
400  CLASS::localSetIntrinsicSA(const GA_IntrinsicEval &eval, \
401  const UT_StringArray &v) \
402 { \
403  int id = eval.getUserId(_theIntrinsics##CLASS); \
404  if (id >= 0 && id < _theEval##CLASS.entries()) \
405  return _theEval##CLASS.setSA(id, this, v); \
406  return BASECLASS::localSetIntrinsicSA(eval, v); \
407 } \
408  GA_Size \
409  CLASS::localSetIntrinsicDS(const GA_IntrinsicEval &eval, \
410  const UT_OptionsHolder *v, GA_Size size) \
411 { \
412  int id = eval.getUserId(_theIntrinsics##CLASS); \
413  if (id >= 0 && id < _theEval##CLASS.entries()) \
414  return _theEval##CLASS.setDS(id, this, v, size); \
415  return BASECLASS::localSetIntrinsicDS(eval, v, size); \
416 } \
417  GA_Size \
418  CLASS::localSetIntrinsicDA(const GA_IntrinsicEval &eval, \
419  const UT_Array<UT_OptionsHolder> &v) \
420 { \
421  int id = eval.getUserId(_theIntrinsics##CLASS); \
422  if (id >= 0 && id < _theEval##CLASS.entries()) \
423  return _theEval##CLASS.setDA(id, this, v); \
424  return BASECLASS::localSetIntrinsicDA(eval, v); \
425 }
426 
427  // ----------- Intrinsic definition macros start here ------------
428 #define GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, STORAGE) \
429  myEval[ID].myId = ID; \
430  myEval[ID].myName = NAME; \
431  myEval[ID].myStore = STORAGE; \
432  myEval[ID].myTupleSize = TUPLESIZE;
433 #define GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, STORAGE) \
434  myEval[ID].myId = ID; \
435  myEval[ID].myName = NAME; \
436  myEval[ID].myStore = STORAGE; \
437  myEval[ID].myTupleSizeCB = TUPLESIZE_FUNC;
438 
439  // Set UT_Options bound to intrinsic definition. You might consider storing
440  // information about attribute in the options (i.e. "type":GA_TypeInfo). This
441  // is totally optional.
442 #define GA_INTRINSIC_OPTIONS(ID, OPTIONS) \
443  myEval[ID].myOptions = &OPTIONS;
444 
445  // Set the collapse of singleton tuples to scalars flag for
446  // this intrinsic. The flag defaults to true, so you only
447  // need to use this macro if you want to set it to false.
448 #define GA_INTRINSIC_COLLAPSE_SINGLETONS(ID, BOOL) \
449  myEval[ID].myCollapseSingletons = BOOL;
450 
451  // Integer intrinsics
452 #define GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
453  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_INT)
454 
455 #define GA_INTRINSIC_DEF_VARYING_I(ID, NAME, TUPLESIZE_FUNC) \
456  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_INT)
457 
458 #define GA_INTRINSIC_I(CLASS, ID, NAME, EVAL) { \
459  struct callbacks { \
460  static GA_Size eval(const CLASS *o, int64 *v, GA_Size) \
461  { v[0] = EVAL(o); return 1; } \
462  static GA_Size evalF(const CLASS *o, fpreal64 *v, GA_Size) \
463  { v[0] = EVAL(o); return 1; } \
464  }; \
465  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
466  myEval[ID].myI = callbacks::eval; \
467  myEval[ID].myF = callbacks::evalF; \
468 }
469 #define GA_INTRINSIC_CONST_I(CLASS, ID, NAME, VALUE) { \
470  struct callbacks { \
471  static GA_Size eval(const CLASS *, int64 *v, GA_Size) \
472  { v[0] = VALUE; return 1; } \
473  static GA_Size evalF(const CLASS *, fpreal64 *v, GA_Size) \
474  { v[0] = VALUE; return 1; } \
475  }; \
476  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
477  myEval[ID].myI = callbacks::eval; \
478  myEval[ID].myF = callbacks::evalF; \
479 }
480 #define GA_INTRINSIC_METHOD_I(CLASS, ID, NAME, METHOD) { \
481  struct callbacks { \
482  static GA_Size eval(const CLASS *o, int64 *v, GA_Size) \
483  { v[0] = o->METHOD(); return 1; } \
484  static GA_Size evalF(const CLASS *o, fpreal64 *v, GA_Size) \
485  { v[0] = o->METHOD(); return 1; } \
486  }; \
487  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
488  myEval[ID].myI = callbacks::eval; \
489  myEval[ID].myF = callbacks::evalF; \
490 }
491 #define GA_INTRINSIC_TUPLE_I(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
492  struct callbacks { \
493  static GA_Size evalF(const CLASS *o, fpreal64 *v, GA_Size sz) \
494  { int64 tmp[TUPLESIZE]; \
495  int result = EVAL(o, tmp, SYSmin(sz, TUPLESIZE)); \
496  for (int i = 0; i < SYSmin(sz, TUPLESIZE); i++) \
497  v[i] = tmp[i]; \
498  return result; } \
499  }; \
500  GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
501  myEval[ID].myI = EVAL; \
502  myEval[ID].myF = callbacks::evalF; \
503 }
504 #define GA_INTRINSIC_TUPLE_METHOD_I(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
505  struct callbacks { \
506  static GA_Size eval(const CLASS *o, int64 *v, GA_Size sz) \
507  { return o->EVAL(v, sz); } \
508  static GA_Size evalF(const CLASS *o, fpreal64 *v, GA_Size sz) \
509  { int64 tmp[TUPLESIZE]; \
510  int result = o->EVAL(tmp, SYSmin(sz, TUPLESIZE)); \
511  for (exint i = 0; i < SYSmin(sz, TUPLESIZE); i++) { v[i] = tmp[i]; } \
512  return result; } \
513  }; \
514  GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
515  myEval[ID].myI = callbacks::eval; \
516 }
517 #define GA_INTRINSIC_ARRAY_I(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
518  struct callbacks { \
519  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
520  static GA_Size eval(const CLASS *o, int64 *v, GA_Size size) \
521  { \
522  const ARRAY_TYPE &array = o->METHOD(); \
523  size = SYSmin(size, array.entries()); \
524  for (exint i = 0; i < size; ++i) { v[i] = array(i); } \
525  return size; \
526  } \
527  }; \
528  GA_INTRINSIC_DEF_VARYING_I(ID, NAME, callbacks::tsize) \
529  myEval[ID].myI = callbacks::eval; \
530 }
531 #define GA_INTRINSIC_VARYING_I(CLASS, ID, NAME, TSIZE, EVAL) { \
532  GA_INTRINSIC_DEF_VARYING_I(ID, NAME, TSIZE) \
533  myEval[ID].myI = EVAL; \
534 }
535 
536 #define GA_INTRINSIC_SET_I(CLASS, ID, SETFUNC) { \
537  struct callbacks { \
538  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
539  { return SETFUNC(o, v[0]) ? 1 : 0; } \
540  static GA_Size setFuncF(CLASS *o, const fpreal64 *v, GA_Size sz) \
541  { return SETFUNC(o, v[0]) ? 1 : 0; } \
542  }; \
543  myEval[ID].mySetI = callbacks::setFunc; \
544  myEval[ID].mySetF = callbacks::setFuncF; \
545  myEval[ID].myReadOnly = false; \
546 }
547 #define GA_INTRINSIC_SET_METHOD_I(CLASS, ID, METHOD) { \
548  struct callbacks { \
549  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
550  { return o->METHOD(v[0]) ? 1 : 0; } \
551  static GA_Size setFuncF(CLASS *o, const fpreal64 *v, GA_Size sz) \
552  { return o->METHOD(v[0]) ? 1 : 0; } \
553  }; \
554  myEval[ID].mySetI = callbacks::setFunc; \
555  myEval[ID].mySetF = callbacks::setFuncF; \
556  myEval[ID].myReadOnly = false; \
557 }
558 #define GA_INTRINSIC_SET_TUPLE_I(CLASS, ID, SETFUNC) { \
559  struct callbacks { \
560  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
561  { return SETFUNC(o, v, sz); } \
562  static GA_Size setFuncF(CLASS *o, const fpreal64 *v, GA_Size sz) \
563  { \
564  int64 *tmp = (int64 *)UTstackAlloc(sizeof(int64) * sz); \
565  for (exint i = 0; i < sz; i++) { tmp[i] = v[i]; } \
566  int result = SETFUNC(o, tmp, sz); \
567  UTstackFree(tmp); \
568  return result; \
569  } \
570  }; \
571  myEval[ID].mySetI = callbacks::setFunc; \
572  myEval[ID].mySetF = callbacks::setFuncF; \
573  myEval[ID].myReadOnly = false; \
574 }
575 #define GA_INTRINSIC_SET_TUPLE_METHOD_I(CLASS, ID, METHOD) { \
576  struct callbacks { \
577  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
578  { return o->METHOD(v[0], sz); } \
579  static GA_Size setFuncF(CLASS *o, const fpreal64 *v, GA_Size sz) \
580  { \
581  int64 *tmp = (int64 *)UTstackAlloc(sizeof(int64) * sz); \
582  for (exint i = 0; i < sz; i++) { tmp[i] = v[i]; } \
583  int result = o->SETFUNC(tmp, sz); \
584  UTstackFree(tmp); \
585  return result; \
586  } \
587  }; \
588  myEval[ID].mySetI = callbacks::setFunc; \
589  myEval[ID].mySetF = callbacks::setFuncF; \
590  myEval[ID].myReadOnly = false; \
591 }
592 
593  // Float intrinsics
594 #define GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
595  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_FLOAT)
596 
597 #define GA_INTRINSIC_DEF_VARYING_F(ID, NAME, TUPLESIZE_FUNC) \
598  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_FLOAT)
599 
600 #define GA_INTRINSIC_F(CLASS, ID, NAME, EVAL) { \
601  struct callbacks { \
602  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size) \
603  { v[0] = EVAL(o); return 1; } \
604  }; \
605  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
606  myEval[ID].myF = callbacks::eval; \
607 }
608 #define GA_INTRINSIC_CONST_F(CLASS, ID, NAME, VALUE) { \
609  struct callbacks { \
610  static GA_Size eval(const CLASS *, fpreal64 *v, GA_Size) \
611  { v[0] = VALUE; return 1; } \
612  }; \
613  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
614  myEval[ID].myF = callbacks::eval; \
615 }
616 #define GA_INTRINSIC_METHOD_F(CLASS, ID, NAME, METHOD) { \
617  struct callbacks { \
618  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size) \
619  { v[0] = o->METHOD(); return 1; } \
620  }; \
621  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
622  myEval[ID].myF = callbacks::eval; \
623 }
624 #define GA_INTRINSIC_TUPLE_F(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
625  GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
626  myEval[ID].myF = EVAL; \
627 }
628 #define GA_INTRINSIC_TUPLE_METHOD_F(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
629  struct callbacks { \
630  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size sz) \
631  { return o->EVAL(v, sz); } \
632  }; \
633  GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
634  myEval[ID].myF = callbacks::eval; \
635 }
636 #define GA_INTRINSIC_ARRAY_F(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
637  struct callbacks { \
638  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
639  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size size) \
640  { \
641  const ARRAY_TYPE &array = o->METHOD(); \
642  size = SYSmin(size, array.entries()); \
643  for (exint i = 0; i < size; ++i) { v[i] = array(i); } \
644  return size; \
645  } \
646  }; \
647  GA_INTRINSIC_DEF_VARYING_F(ID, NAME, callbacks::tsize) \
648  myEval[ID].myF = callbacks::eval; \
649 }
650 #define GA_INTRINSIC_VARYING_F(CLASS, ID, NAME, TSIZE, EVAL) { \
651  GA_INTRINSIC_DEF_VARYING_F(ID, NAME, TSIZE) \
652  myEval[ID].myF = EVAL; \
653 }
654 
655 #define GA_INTRINSIC_SET_F(CLASS, ID, SETFUNC) { \
656  struct callbacks { \
657  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
658  { SETFUNC(o, v[0]); return 1; } \
659  }; \
660  myEval[ID].mySetF = callbacks::setFunc; \
661  myEval[ID].myReadOnly = false; \
662 }
663 #define GA_INTRINSIC_SET_METHOD_F(CLASS, ID, METHOD) { \
664  struct callbacks { \
665  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
666  { o->METHOD(v[0]); return 1; } \
667  }; \
668  myEval[ID].mySetF = callbacks::setFunc; \
669  myEval[ID].myReadOnly = false; \
670 }
671 #define GA_INTRINSIC_SET_TUPLE_F(CLASS, ID, SETFUNC) { \
672  struct callbacks { \
673  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
674  { return SETFUNC(o, v, sz); } \
675  }; \
676  myEval[ID].mySetF = callbacks::setFunc; \
677  myEval[ID].myReadOnly = false; \
678 }
679 #define GA_INTRINSIC_SET_TUPLE_METHOD_F(CLASS, ID, METHOD) { \
680  struct callbacks { \
681  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
682  { return o->METHOD(v[0], sz); } \
683  }; \
684  myEval[ID].mySetF = callbacks::setFunc; \
685  myEval[ID].myReadOnly = false; \
686 }
687 
688  // String intrinsics
689 #define GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
690  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_STRING)
691 
692 #define GA_INTRINSIC_DEF_VARYING_S(ID, NAME, TUPLESIZE_FUNC) \
693  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_STRING)
694 
695 #define GA_INTRINSIC_S(CLASS, ID, NAME, EVAL) { \
696  struct callbacks { \
697  static GA_Size evalS(const CLASS *o, UT_String &v) \
698  { v = EVAL(o); return 1; } \
699  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
700  { v.append(EVAL(o)); return 1; } \
701  }; \
702  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
703  myEval[ID].myS = callbacks::evalS; \
704  myEval[ID].mySA = callbacks::evalSA; \
705 }
706 #define GA_INTRINSIC_CONST_S(CLASS, ID, NAME, VALUE) { \
707  struct callbacks { \
708  static GA_Size evalS(const CLASS *, UT_String &v) \
709  { v = VALUE; return 1; } \
710  static GA_Size evalSA(const CLASS *, UT_StringArray &v) \
711  { v.append(VALUE); return 1; } \
712  }; \
713  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
714  myEval[ID].myS = callbacks::evalS; \
715  myEval[ID].mySA = callbacks::evalSA; \
716 }
717 #define GA_INTRINSIC_METHOD_S(CLASS, ID, NAME, METHOD) { \
718  struct callbacks { \
719  static GA_Size evalS(const CLASS *o, UT_String &v) \
720  { v = o->METHOD(); return 1; } \
721  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
722  { v.append(o->METHOD()); return 1; } \
723  }; \
724  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
725  myEval[ID].myS = callbacks::evalS; \
726  myEval[ID].mySA = callbacks::evalSA; \
727 }
728 #define GA_INTRINSIC_TUPLE_S(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
729  GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
730  myEval[ID].mySA = EVAL; \
731 }
732 #define GA_INTRINSIC_TUPLE_METHOD_S(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
733  struct callbacks { \
734  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
735  { o->EVAL(v); return v.entries(); } \
736  }; \
737  GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
738  myEval[ID].mySA = callbacks::eval; \
739 }
740 #define GA_INTRINSIC_ARRAY_S(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
741  struct callbacks { \
742  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
743  static GA_Size eval(const CLASS *o, UT_StringArray &v) \
744  { \
745  const ARRAY_TYPE &array = o->METHOD(); \
746  for (exint i = 0; i < size; ++i) { v[i].append(array(i)); } \
747  return v.entries(); \
748  } \
749  }; \
750  GA_INTRINSIC_DEF_VARYING_S(ID, NAME, callbacks::tsize) \
751  myEval[ID].mySA = callbacks::eval; \
752 }
753 #define GA_INTRINSIC_VARYING_S(CLASS, ID, NAME, TSIZE, EVAL) { \
754  GA_INTRINSIC_DEF_VARYING_S(ID, NAME, TSIZE) \
755  myEval[ID].mySA = EVAL; \
756 }
757 
758 #define GA_INTRINSIC_SET_S(CLASS, ID, SETFUNC) { \
759  struct callbacks { \
760  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
761  { return SETFUNC(o, v[0]) ? 1 : 0; } \
762  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
763  { return SETFUNC(o, a(0)) ? 1 : 0; } \
764  }; \
765  myEval[ID].mySetSS = callbacks::setSS; \
766  myEval[ID].mySetSA = callbacks::setSA; \
767  myEval[ID].myReadOnly = false; \
768 }
769 #define GA_INTRINSIC_SET_METHOD_S(CLASS, ID, METHOD) { \
770  struct callbacks { \
771  static GA_Size setSS(CLASS *o, const char **v, GA_Size) \
772  { return o->METHOD(v[0]) ? 1 : 0; } \
773  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
774  { return o->METHOD(a(0)) ? 1 : 0; } \
775  }; \
776  myEval[ID].mySetSS = callbacks::setSS; \
777  myEval[ID].mySetSA = callbacks::setSA; \
778  myEval[ID].myReadOnly = false; \
779 }
780 #define GA_INTRINSIC_SET_TUPLE_S(CLASS, ID, SETFUNC) { \
781  struct callbacks { \
782  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
783  { return SETFUNC(o, a); } \
784  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
785  { \
786  UT_StringArray array; \
787  array.resize(sz); \
788  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
789  return SETFUNC(o, array); \
790  } \
791  }; \
792  myEval[ID].mySetSS = callbacks::setSS; \
793  myEval[ID].mySetSA = callbacks::setSA; \
794  myEval[ID].myReadOnly = false; \
795 }
796 #define GA_INTRINSIC_SET_TUPLE_METHOD_S(CLASS, ID, METHOD) { \
797  struct callbacks { \
798  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
799  { return o->METHOD(a); } \
800  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
801  { \
802  UT_StringArray array; \
803  array.resize(sz); \
804  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
805  return o->METHOD(array); \
806  } \
807  }; \
808  myEval[ID].mySetSS = callbacks::setSS; \
809  myEval[ID].mySetSA = callbacks::setSA; \
810  myEval[ID].myReadOnly = false; \
811 }
812 
813  // Dictionary intrinsics
814 #define GA_INTRINSIC_DEF_D(ID, NAME, TUPLESIZE) \
815  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_DICT)
816 
817 #define GA_INTRINSIC_DEF_VARYING_D(ID, NAME, TUPLESIZE_FUNC) \
818  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_DICT)
819 
820 #define GA_INTRINSIC_D(CLASS, ID, NAME, EVAL) { \
821  struct callbacks { \
822  static GA_Size evalD(const CLASS *o, UT_OptionsHolder &v) \
823  { v = EVAL(o); return 1; } \
824  static GA_Size evalDA(const CLASS *o, UT_Array<UT_OptionsHolder> &v) \
825  { v.append(EVAL(o)); return 1; } \
826  }; \
827  GA_INTRINSIC_DEF_D(ID, NAME, 1) \
828  myEval[ID].myD = callbacks::evalD; \
829  myEval[ID].myDA = callbacks::evalDA; \
830  }
831 #define GA_INTRINSIC_CONST_D(CLASS, ID, NAME, VALUE) { \
832  struct callbacks { \
833  static GA_Size evalD(const CLASS *, UT_OptionsHolder &v) \
834  { v = VALUE; return 1; } \
835  static GA_Size evalDA(const CLASS *, UT_Array<UT_OptionsHolder> &v) \
836  { v.append(VALUE); return 1; } \
837  }; \
838  GA_INTRINSIC_DEF_D(ID, NAME, 1) \
839  myEval[ID].myD = callbacks::evalD; \
840  myEval[ID].myDA = callbacks::evalDA; \
841  }
842 #define GA_INTRINSIC_METHOD_D(CLASS, ID, NAME, METHOD) { \
843  struct callbacks { \
844  static GA_Size evalD(const CLASS *o, UT_OptionsHolder &v) \
845  { v = o->METHOD(); return 1; } \
846  static GA_Size evalDA(const CLASS *o, UT_Array<UT_OptionsHolder> &v) \
847  { v.append(o->METHOD()); return 1; } \
848  }; \
849  GA_INTRINSIC_DEF_D(ID, NAME, 1) \
850  myEval[ID].myD = callbacks::evalD; \
851  myEval[ID].myDA = callbacks::evalDA; \
852  }
853 #define GA_INTRINSIC_TUPLE_D(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
854  GA_INTRINSIC_DEF_D(ID, NAME, TUPLESIZE) \
855  myEval[ID].myDA = EVAL; \
856  }
857 #define GA_INTRINSIC_TUPLE_METHOD_D(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
858  struct callbacks { \
859  static GA_Size evalDA(const CLASS *o, UT_Array<UT_OptionsHolder> &v) \
860  { o->EVAL(v); return v.entries(); } \
861  }; \
862  GA_INTRINSIC_DEF_D(ID, NAME, TUPLESIZE) \
863  myEval[ID].myDA = callbacks::eval; \
864  }
865 #define GA_INTRINSIC_ARRAY_D(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
866  struct callbacks { \
867  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
868  static GA_Size eval(const CLASS *o, UT_Array<UT_OptionsHolder> &v) \
869  { \
870  const ARRAY_TYPE &array = o->METHOD(); \
871  for (exint i = 0; i < size; ++i) { v[i].append(array(i)); } \
872  return v.entries(); \
873  } \
874  }; \
875  GA_INTRINSIC_DEF_VARYING_D(ID, NAME, callbacks::tsize) \
876  myEval[ID].myDA = callbacks::eval; \
877  }
878 #define GA_INTRINSIC_VARYING_D(CLASS, ID, NAME, TSIZE, EVAL) { \
879  GA_INTRINSIC_DEF_VARYING_D(ID, NAME, TSIZE) \
880  myEval[ID].myDA = EVAL; \
881  }
882 
883 #define GA_INTRINSIC_SET_D(CLASS, ID, SETFUNC) { \
884  struct callbacks { \
885  static GA_Size setDS(CLASS *o, const UT_OptionsHolder *v, GA_Size sz) \
886  { return SETFUNC(o, v[0]) ? 1 : 0; } \
887  static GA_Size setDA(CLASS *o, const UT_Array<UT_OptionsHolder> &a) \
888  { return SETFUNC(o, a(0)) ? 1 : 0; } \
889  }; \
890  myEval[ID].mySetDS = callbacks::setDS; \
891  myEval[ID].mySetDA = callbacks::setDA; \
892  myEval[ID].myReadOnly = false; \
893  }
894 #define GA_INTRINSIC_SET_METHOD_D(CLASS, ID, METHOD) { \
895  struct callbacks { \
896  static GA_Size setDS(CLASS *o, const UT_OptionsHolder *v, GA_Size) \
897  { return o->METHOD(v[0]) ? 1 : 0; } \
898  static GA_Size setDA(CLASS *o, const UT_Array<UT_OptionsHolder> &a) \
899  { return o->METHOD(a(0)) ? 1 : 0; } \
900  }; \
901  myEval[ID].mySetDS = callbacks::setDS; \
902  myEval[ID].mySetDA = callbacks::setDA; \
903  myEval[ID].myReadOnly = false; \
904  }
905 #define GA_INTRINSIC_SET_TUPLE_D(CLASS, ID, SETFUNC) { \
906  struct callbacks { \
907  static GA_Size setDA(CLASS *o, const UT_Array<UT_OptionsHolder> &a) \
908  { return SETFUNC(o, a); } \
909  static GA_Size setDS(CLASS *o, const UT_OptionsHolder *v, GA_Size sz) \
910  { \
911  UT_Array<UT_OptionsHolder> array; \
912  array.resize(sz); \
913  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
914  return SETFUNC(o, array); \
915  } \
916  }; \
917  myEval[ID].mySetDS = callbacks::setDS; \
918  myEval[ID].mySetDA = callbacks::setDA; \
919  myEval[ID].myReadOnly = false; \
920  }
921 #define GA_INTRINSIC_SET_TUPLE_METHOD_D(CLASS, ID, METHOD) { \
922  struct callbacks { \
923  static GA_Size setDA(CLASS *o, const UT_Array<UT_OptionsHolder> &a) \
924  { return o->METHOD(a); } \
925  static GA_Size setDS(CLASS *o, const UT_OptionsHolder *v, GA_Size sz) \
926  { \
927  UT_Array<UT_OptionsHolder> array; \
928  array.resize(sz); \
929  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
930  return o->METHOD(array); \
931  } \
932  }; \
933  myEval[ID].mySetDS = callbacks::setDS; \
934  myEval[ID].mySetDA = callbacks::setDA; \
935  myEval[ID].myReadOnly = false; \
936  }
937 #endif
938