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  { \
181  } \
182  GA_Size getTupleSize(const CLASS *o) const \
183  { \
184  if (myTupleSize > 0) return myTupleSize; \
185  return myTupleSizeCB(o); \
186  } \
187  void dump() { \
188  fprintf(stderr, "Intrinsic[%d] := {\n", myId); \
189  fprintf(stderr, " 'name' : '%s'\n", myName); \
190  fprintf(stderr, " 'tuple' : %d\n", (int)myTupleSize); \
191  fprintf(stderr, " 'storage' : %s\n", GAstorageClass(myStore));\
192  fprintf(stderr, " 'ro' : %d\n", myReadOnly); \
193  fprintf(stderr, " 'tuple()' : %p\n", myTupleSizeCB); \
194  fprintf(stderr, " 'options' : %p\n", myOptions); \
195  fprintf(stderr, " 'I()' : %p\n", myI); \
196  fprintf(stderr, " 'F()' : %p\n", myF); \
197  fprintf(stderr, " 'S()' : %p\n", myS); \
198  fprintf(stderr, " 'SA()' : %p\n", mySA); \
199  fprintf(stderr, " 'D()' : %p\n", myD); \
200  fprintf(stderr, " 'DA()' : %p\n", myDA); \
201  fprintf(stderr, " 'setI()' : %p\n", mySetI); \
202  fprintf(stderr, " 'setF()' : %p\n", mySetF); \
203  fprintf(stderr, " 'setSS()' : %p\n", mySetSS); \
204  fprintf(stderr, " 'setSA()' : %p\n", mySetSA); \
205  fprintf(stderr, " 'setDS()' : %p\n", mySetDS); \
206  fprintf(stderr, " 'setDA()' : %p\n", mySetDA); \
207  } \
208  bool valid(int index) const \
209  { \
210  if (myName && myId >= 0 && myStore != GA_STORECLASS_INVALID \
211  && (myTupleSize > 0 || myTupleSizeCB) \
212  && (myI || myF || myS || mySA)) \
213  return true; \
214  fprintf(stderr, "Warning: missing intrinsic for %s[%d]\n", \
215 #CLASS, index); \
216  return false; \
217  } \
218  cbTupleSize myTupleSizeCB; \
219  cbEvalI myI; \
220  cbEvalF myF; \
221  cbEvalS myS; \
222  cbEvalSA mySA; \
223  cbEvalD myD; \
224  cbEvalDA myDA; \
225  cbSetI mySetI; \
226  cbSetF mySetF; \
227  cbSetS mySetSS; \
228  cbSetSA mySetSA; \
229  cbSetD mySetDS; \
230  cbSetDA mySetDA; \
231  const char *myName; \
232  const UT_Options *myOptions; \
233  GA_Size myTupleSize; \
234  int myId; \
235  GA_StorageClass myStore; \
236  bool myReadOnly; \
237  }; \
238  Eval myEval[NUM_INTRINSICS]; \
239  int entries() const { return NUM_INTRINSICS; } \
240  bool valid(int i) const { return myEval[i].valid(i); } \
241  GA_Size getTupleSize(int i, const CLASS *o) const \
242  { return myEval[i].getTupleSize(o); } \
243  GA_Size evalI(int i, const CLASS *o, int64 *v, GA_Size n) const \
244  { return myEval[i].myI(o, v, n); } \
245  GA_Size evalF(int i, const CLASS *o, fpreal64 *v, GA_Size n) const \
246  { return myEval[i].myF(o, v, n); } \
247  GA_Size evalS(int i, const CLASS *o, UT_String &v) const \
248  { return myEval[i].myS(o, v); } \
249  GA_Size evalSA(int i, const CLASS *o, UT_StringArray &v) const \
250  { return myEval[i].mySA(o, v); } \
251  GA_Size evalD(int i, const CLASS *o, UT_OptionsHolder &v) const \
252  { return myEval[i].myD(o, v); } \
253  GA_Size evalDA(int i, const CLASS *o, UT_Array<UT_OptionsHolder> &v) const \
254  { return myEval[i].myDA(o, v); } \
255  GA_Size setI(int i, CLASS *o, const int64 *v, GA_Size n) const \
256  { return myEval[i].mySetI(o, v, n); } \
257  GA_Size setF(int i, CLASS *o, const fpreal64 *v, GA_Size n) const \
258  { return myEval[i].mySetF(o, v, n); } \
259  GA_Size setSS(int i, CLASS *o, const char **v, GA_Size n) const \
260  { return myEval[i].mySetSS(o, v, n); } \
261  GA_Size setSA(int i, CLASS *o, const UT_StringArray &v) const \
262  { return myEval[i].mySetSA(o, v); } \
263  GA_Size setDS(int i, CLASS *o, const UT_OptionsHolder *v, GA_Size n) const \
264  { return myEval[i].mySetDS(o, v, n); } \
265  GA_Size setDA(int i, CLASS *o, const UT_Array<UT_OptionsHolder> &v) const \
266  { return myEval[i].mySetDA(o, v); } \
267  GA_StorageClass getStorageClass(int i) const \
268  { return myEval[i].myStore; } \
269  const char *getName(int i) const { return myEval[i].myName; } \
270  int getId(int i) const { return myEval[i].myId; } \
271  bool getReadOnly(int i) const { return myEval[i].myReadOnly; } \
272  const UT_Options *getOptions(int i) const \
273  { return myEval[i].myOptions; } \
274  _ga_intrinsicEvaluator##CLASS() {
275 
276 #define GA_END_INTRINSIC_DEF(CLASS, BASECLASS) \
277  } \
278  }; \
279  static GA_IntrinsicDef _theIntrinsics##CLASS; \
280  static _ga_intrinsicEvaluator##CLASS _theEval##CLASS; \
281 } \
282  GA_IntrinsicManager::Registrar \
283  CLASS::registerIntrinsics(GA_PrimitiveDefinition &defn) \
284 { \
285  GA_IntrinsicManager::Registrar r(BASECLASS::registerIntrinsics(defn)); \
286  if (r.start(_theIntrinsics##CLASS)) \
287  { \
288  for (int i = 0; i < _theEval##CLASS.entries(); ++i) \
289  { \
290  UT_ASSERT(_theEval##CLASS.getName(i)); \
291  if (_theEval##CLASS.valid(i)) \
292  { \
293  r.addAttribute(_theEval##CLASS.getStorageClass(i), \
294  _theEval##CLASS.getName(i), \
295  _theEval##CLASS.getId(i), \
296  _theEval##CLASS.getReadOnly(i), \
297  _theEval##CLASS.getOptions(i)); \
298  } \
299  } \
300  } \
301  return r; \
302 } \
303  GA_Size \
304  CLASS::localIntrinsicTupleSize(const GA_IntrinsicEval &eval) const \
305 { \
306  int id = eval.getUserId(_theIntrinsics##CLASS); \
307  if (id >= 0 && id < _theEval##CLASS.entries()) \
308  return _theEval##CLASS.getTupleSize(id, this); \
309  return BASECLASS::localIntrinsicTupleSize(eval); \
310 } \
311  GA_Size \
312  CLASS::localGetIntrinsicI(const GA_IntrinsicEval &eval, \
313  int64 *v, GA_Size size) const \
314 { \
315  int id = eval.getUserId(_theIntrinsics##CLASS); \
316  if (id >= 0 && id < _theEval##CLASS.entries()) \
317  return _theEval##CLASS.evalI(id, this, v, size); \
318  return BASECLASS::localGetIntrinsicI(eval, v, size); \
319 } \
320  GA_Size \
321  CLASS::localGetIntrinsicF(const GA_IntrinsicEval &eval, \
322  fpreal64 *v, GA_Size size) const \
323 { \
324  int id = eval.getUserId(_theIntrinsics##CLASS); \
325  if (id >= 0 && id < _theEval##CLASS.entries()) \
326  return _theEval##CLASS.evalF(id, this, v, size); \
327  return BASECLASS::localGetIntrinsicF(eval, v, size); \
328 } \
329  GA_Size \
330  CLASS::localGetIntrinsicS(const GA_IntrinsicEval &eval, \
331  UT_String &v) const \
332 { \
333  int id = eval.getUserId(_theIntrinsics##CLASS); \
334  if (id >= 0 && id < _theEval##CLASS.entries()) \
335  return _theEval##CLASS.evalS(id, this, v); \
336  return BASECLASS::localGetIntrinsicS(eval, v); \
337 } \
338  GA_Size \
339  CLASS::localGetIntrinsicSA(const GA_IntrinsicEval &eval, \
340  UT_StringArray &v) const \
341 { \
342  int id = eval.getUserId(_theIntrinsics##CLASS); \
343  if (id >= 0 && id < _theEval##CLASS.entries()) \
344  return _theEval##CLASS.evalSA(id, this, v); \
345  return BASECLASS::localGetIntrinsicSA(eval, v); \
346 } \
347  GA_Size \
348  CLASS::localGetIntrinsicD(const GA_IntrinsicEval &eval, \
349  UT_OptionsHolder &v) const \
350 { \
351  int id = eval.getUserId(_theIntrinsics##CLASS); \
352  if (id >= 0 && id < _theEval##CLASS.entries()) \
353  return _theEval##CLASS.evalD(id, this, v); \
354  return BASECLASS::localGetIntrinsicD(eval, v); \
355 } \
356  GA_Size \
357  CLASS::localGetIntrinsicDA(const GA_IntrinsicEval &eval, \
358  UT_Array<UT_OptionsHolder> &v) const \
359 { \
360  int id = eval.getUserId(_theIntrinsics##CLASS); \
361  if (id >= 0 && id < _theEval##CLASS.entries()) \
362  return _theEval##CLASS.evalDA(id, this, v); \
363  return BASECLASS::localGetIntrinsicDA(eval, v); \
364 } \
365  GA_Size \
366  CLASS::localSetIntrinsicI(const GA_IntrinsicEval &eval, \
367  const int64 *v, GA_Size size) \
368 { \
369  int id = eval.getUserId(_theIntrinsics##CLASS); \
370  if (id >= 0 && id < _theEval##CLASS.entries()) \
371  return _theEval##CLASS.setI(id, this, v, size); \
372  return BASECLASS::localSetIntrinsicI(eval, v, size); \
373 } \
374  GA_Size \
375  CLASS::localSetIntrinsicF(const GA_IntrinsicEval &eval, \
376  const fpreal64 *v, GA_Size size) \
377 { \
378  int id = eval.getUserId(_theIntrinsics##CLASS); \
379  if (id >= 0 && id < _theEval##CLASS.entries()) \
380  return _theEval##CLASS.setF(id, this, v, size); \
381  return BASECLASS::localSetIntrinsicF(eval, v, size); \
382 } \
383  GA_Size \
384  CLASS::localSetIntrinsicSS(const GA_IntrinsicEval &eval, \
385  const char **v, GA_Size size) \
386 { \
387  int id = eval.getUserId(_theIntrinsics##CLASS); \
388  if (id >= 0 && id < _theEval##CLASS.entries()) \
389  return _theEval##CLASS.setSS(id, this, v, size); \
390  return BASECLASS::localSetIntrinsicSS(eval, v, size); \
391 } \
392  GA_Size \
393  CLASS::localSetIntrinsicSA(const GA_IntrinsicEval &eval, \
394  const UT_StringArray &v) \
395 { \
396  int id = eval.getUserId(_theIntrinsics##CLASS); \
397  if (id >= 0 && id < _theEval##CLASS.entries()) \
398  return _theEval##CLASS.setSA(id, this, v); \
399  return BASECLASS::localSetIntrinsicSA(eval, v); \
400 } \
401  GA_Size \
402  CLASS::localSetIntrinsicDS(const GA_IntrinsicEval &eval, \
403  const UT_OptionsHolder *v, GA_Size size) \
404 { \
405  int id = eval.getUserId(_theIntrinsics##CLASS); \
406  if (id >= 0 && id < _theEval##CLASS.entries()) \
407  return _theEval##CLASS.setDS(id, this, v, size); \
408  return BASECLASS::localSetIntrinsicDS(eval, v, size); \
409 } \
410  GA_Size \
411  CLASS::localSetIntrinsicDA(const GA_IntrinsicEval &eval, \
412  const UT_Array<UT_OptionsHolder> &v) \
413 { \
414  int id = eval.getUserId(_theIntrinsics##CLASS); \
415  if (id >= 0 && id < _theEval##CLASS.entries()) \
416  return _theEval##CLASS.setDA(id, this, v); \
417  return BASECLASS::localSetIntrinsicDA(eval, v); \
418 }
419 
420  // ----------- Intrinsic definition macros start here ------------
421 #define GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, STORAGE) \
422  myEval[ID].myId = ID; \
423  myEval[ID].myName = NAME; \
424  myEval[ID].myStore = STORAGE; \
425  myEval[ID].myTupleSize = TUPLESIZE;
426 #define GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, STORAGE) \
427  myEval[ID].myId = ID; \
428  myEval[ID].myName = NAME; \
429  myEval[ID].myStore = STORAGE; \
430  myEval[ID].myTupleSizeCB = TUPLESIZE_FUNC;
431 
432  // Set UT_Options bound to intrinsic definition. You might consider storing
433  // information about attribute in the options (i.e. "type":GA_TypeInfo). This
434  // is totally optional.
435 #define GA_INTRINSIC_OPTIONS(ID, OPTIONS) \
436  myEval[ID].myOptions = &OPTIONS;
437 
438  // Integer intrinsics
439 #define GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
440  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_INT)
441 
442 #define GA_INTRINSIC_DEF_VARYING_I(ID, NAME, TUPLESIZE_FUNC) \
443  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_INT)
444 
445 #define GA_INTRINSIC_I(CLASS, ID, NAME, EVAL) { \
446  struct callbacks { \
447  static GA_Size eval(const CLASS *o, int64 *v, GA_Size) \
448  { v[0] = EVAL(o); return 1; } \
449  static GA_Size evalF(const CLASS *o, fpreal64 *v, GA_Size) \
450  { v[0] = EVAL(o); return 1; } \
451  }; \
452  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
453  myEval[ID].myI = callbacks::eval; \
454  myEval[ID].myF = callbacks::evalF; \
455 }
456 #define GA_INTRINSIC_CONST_I(CLASS, ID, NAME, VALUE) { \
457  struct callbacks { \
458  static GA_Size eval(const CLASS *, int64 *v, GA_Size) \
459  { v[0] = VALUE; return 1; } \
460  static GA_Size evalF(const CLASS *, fpreal64 *v, GA_Size) \
461  { v[0] = VALUE; return 1; } \
462  }; \
463  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
464  myEval[ID].myI = callbacks::eval; \
465  myEval[ID].myF = callbacks::evalF; \
466 }
467 #define GA_INTRINSIC_METHOD_I(CLASS, ID, NAME, METHOD) { \
468  struct callbacks { \
469  static GA_Size eval(const CLASS *o, int64 *v, GA_Size) \
470  { v[0] = o->METHOD(); return 1; } \
471  static GA_Size evalF(const CLASS *o, fpreal64 *v, GA_Size) \
472  { v[0] = o->METHOD(); return 1; } \
473  }; \
474  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
475  myEval[ID].myI = callbacks::eval; \
476  myEval[ID].myF = callbacks::evalF; \
477 }
478 #define GA_INTRINSIC_TUPLE_I(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
479  struct callbacks { \
480  static GA_Size evalF(const CLASS *o, fpreal64 *v, GA_Size sz) \
481  { int64 tmp[TUPLESIZE]; \
482  int result = EVAL(o, tmp, SYSmin(sz, TUPLESIZE)); \
483  for (int i = 0; i < SYSmin(sz, TUPLESIZE); i++) \
484  v[i] = tmp[i]; \
485  return result; } \
486  }; \
487  GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
488  myEval[ID].myI = EVAL; \
489  myEval[ID].myF = callbacks::evalF; \
490 }
491 #define GA_INTRINSIC_TUPLE_METHOD_I(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
492  struct callbacks { \
493  static GA_Size eval(const CLASS *o, int64 *v, GA_Size sz) \
494  { return o->EVAL(v, sz); } \
495  static GA_Size evalF(const CLASS *o, fpreal64 *v, GA_Size sz) \
496  { int64 tmp[TUPLESIZE]; \
497  int result = o->EVAL(tmp, SYSmin(sz, TUPLESIZE)); \
498  for (exint i = 0; i < SYSmin(sz, TUPLESIZE); i++) { v[i] = tmp[i]; } \
499  return result; } \
500  }; \
501  GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
502  myEval[ID].myI = callbacks::eval; \
503 }
504 #define GA_INTRINSIC_ARRAY_I(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
505  struct callbacks { \
506  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
507  static GA_Size eval(const CLASS *o, int64 *v, GA_Size size) \
508  { \
509  const ARRAY_TYPE &array = o->METHOD(); \
510  size = SYSmin(size, array.entries()); \
511  for (exint i = 0; i < size; ++i) { v[i] = array(i); } \
512  return size; \
513  } \
514  }; \
515  GA_INTRINSIC_DEF_VARYING_I(ID, NAME, callbacks::tsize) \
516  myEval[ID].myI = callbacks::eval; \
517 }
518 #define GA_INTRINSIC_VARYING_I(CLASS, ID, NAME, TSIZE, EVAL) { \
519  GA_INTRINSIC_DEF_VARYING_I(ID, NAME, TSIZE) \
520  myEval[ID].myI = EVAL; \
521 }
522 
523 #define GA_INTRINSIC_SET_I(CLASS, ID, SETFUNC) { \
524  struct callbacks { \
525  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
526  { return SETFUNC(o, v[0]) ? 1 : 0; } \
527  static GA_Size setFuncF(CLASS *o, const fpreal64 *v, GA_Size sz) \
528  { return SETFUNC(o, v[0]) ? 1 : 0; } \
529  }; \
530  myEval[ID].mySetI = callbacks::setFunc; \
531  myEval[ID].mySetF = callbacks::setFuncF; \
532  myEval[ID].myReadOnly = false; \
533 }
534 #define GA_INTRINSIC_SET_METHOD_I(CLASS, ID, METHOD) { \
535  struct callbacks { \
536  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
537  { return o->METHOD(v[0]) ? 1 : 0; } \
538  static GA_Size setFuncF(CLASS *o, const fpreal64 *v, GA_Size sz) \
539  { return o->METHOD(v[0]) ? 1 : 0; } \
540  }; \
541  myEval[ID].mySetI = callbacks::setFunc; \
542  myEval[ID].mySetF = callbacks::setFuncF; \
543  myEval[ID].myReadOnly = false; \
544 }
545 #define GA_INTRINSIC_SET_TUPLE_I(CLASS, ID, SETFUNC) { \
546  struct callbacks { \
547  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
548  { return SETFUNC(o, v, sz); } \
549  static GA_Size setFuncF(CLASS *o, const fpreal64 *v, GA_Size sz) \
550  { \
551  int64 *tmp = (int64 *)UTstackAlloc(sizeof(int64) * sz); \
552  for (exint i = 0; i < sz; i++) { tmp[i] = v[i]; } \
553  int result = SETFUNC(o, tmp, sz); \
554  UTstackFree(tmp); \
555  return result; \
556  } \
557  }; \
558  myEval[ID].mySetI = callbacks::setFunc; \
559  myEval[ID].mySetF = callbacks::setFuncF; \
560  myEval[ID].myReadOnly = false; \
561 }
562 #define GA_INTRINSIC_SET_TUPLE_METHOD_I(CLASS, ID, METHOD) { \
563  struct callbacks { \
564  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
565  { return o->METHOD(v[0], sz); } \
566  static GA_Size setFuncF(CLASS *o, const fpreal64 *v, GA_Size sz) \
567  { \
568  int64 *tmp = (int64 *)UTstackAlloc(sizeof(int64) * sz); \
569  for (exint i = 0; i < sz; i++) { tmp[i] = v[i]; } \
570  int result = o->SETFUNC(tmp, sz); \
571  UTstackFree(tmp); \
572  return result; \
573  } \
574  }; \
575  myEval[ID].mySetI = callbacks::setFunc; \
576  myEval[ID].mySetF = callbacks::setFuncF; \
577  myEval[ID].myReadOnly = false; \
578 }
579 
580  // Float intrinsics
581 #define GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
582  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_FLOAT)
583 
584 #define GA_INTRINSIC_DEF_VARYING_F(ID, NAME, TUPLESIZE_FUNC) \
585  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_FLOAT)
586 
587 #define GA_INTRINSIC_F(CLASS, ID, NAME, EVAL) { \
588  struct callbacks { \
589  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size) \
590  { v[0] = EVAL(o); return 1; } \
591  }; \
592  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
593  myEval[ID].myF = callbacks::eval; \
594 }
595 #define GA_INTRINSIC_CONST_F(CLASS, ID, NAME, VALUE) { \
596  struct callbacks { \
597  static GA_Size eval(const CLASS *, fpreal64 *v, GA_Size) \
598  { v[0] = VALUE; return 1; } \
599  }; \
600  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
601  myEval[ID].myF = callbacks::eval; \
602 }
603 #define GA_INTRINSIC_METHOD_F(CLASS, ID, NAME, METHOD) { \
604  struct callbacks { \
605  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size) \
606  { v[0] = o->METHOD(); return 1; } \
607  }; \
608  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
609  myEval[ID].myF = callbacks::eval; \
610 }
611 #define GA_INTRINSIC_TUPLE_F(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
612  GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
613  myEval[ID].myF = EVAL; \
614 }
615 #define GA_INTRINSIC_TUPLE_METHOD_F(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
616  struct callbacks { \
617  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size sz) \
618  { return o->EVAL(v, sz); } \
619  }; \
620  GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
621  myEval[ID].myF = callbacks::eval; \
622 }
623 #define GA_INTRINSIC_ARRAY_F(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
624  struct callbacks { \
625  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
626  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size size) \
627  { \
628  const ARRAY_TYPE &array = o->METHOD(); \
629  size = SYSmin(size, array.entries()); \
630  for (exint i = 0; i < size; ++i) { v[i] = array(i); } \
631  return size; \
632  } \
633  }; \
634  GA_INTRINSIC_DEF_VARYING_F(ID, NAME, callbacks::tsize) \
635  myEval[ID].myF = callbacks::eval; \
636 }
637 #define GA_INTRINSIC_VARYING_F(CLASS, ID, NAME, TSIZE, EVAL) { \
638  GA_INTRINSIC_DEF_VARYING_F(ID, NAME, TSIZE) \
639  myEval[ID].myF = EVAL; \
640 }
641 
642 #define GA_INTRINSIC_SET_F(CLASS, ID, SETFUNC) { \
643  struct callbacks { \
644  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
645  { SETFUNC(o, v[0]); return 1; } \
646  }; \
647  myEval[ID].mySetF = callbacks::setFunc; \
648  myEval[ID].myReadOnly = false; \
649 }
650 #define GA_INTRINSIC_SET_METHOD_F(CLASS, ID, METHOD) { \
651  struct callbacks { \
652  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
653  { o->METHOD(v[0]); return 1; } \
654  }; \
655  myEval[ID].mySetF = callbacks::setFunc; \
656  myEval[ID].myReadOnly = false; \
657 }
658 #define GA_INTRINSIC_SET_TUPLE_F(CLASS, ID, SETFUNC) { \
659  struct callbacks { \
660  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
661  { return SETFUNC(o, v, sz); } \
662  }; \
663  myEval[ID].mySetF = callbacks::setFunc; \
664  myEval[ID].myReadOnly = false; \
665 }
666 #define GA_INTRINSIC_SET_TUPLE_METHOD_F(CLASS, ID, METHOD) { \
667  struct callbacks { \
668  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
669  { return o->METHOD(v[0], sz); } \
670  }; \
671  myEval[ID].mySetF = callbacks::setFunc; \
672  myEval[ID].myReadOnly = false; \
673 }
674 
675  // String intrinsics
676 #define GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
677  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_STRING)
678 
679 #define GA_INTRINSIC_DEF_VARYING_S(ID, NAME, TUPLESIZE_FUNC) \
680  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_STRING)
681 
682 #define GA_INTRINSIC_S(CLASS, ID, NAME, EVAL) { \
683  struct callbacks { \
684  static GA_Size evalS(const CLASS *o, UT_String &v) \
685  { v = EVAL(o); return 1; } \
686  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
687  { v.append(EVAL(o)); return 1; } \
688  }; \
689  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
690  myEval[ID].myS = callbacks::evalS; \
691  myEval[ID].mySA = callbacks::evalSA; \
692 }
693 #define GA_INTRINSIC_CONST_S(CLASS, ID, NAME, VALUE) { \
694  struct callbacks { \
695  static GA_Size evalS(const CLASS *, UT_String &v) \
696  { v = VALUE; return 1; } \
697  static GA_Size evalSA(const CLASS *, UT_StringArray &v) \
698  { v.append(VALUE); return 1; } \
699  }; \
700  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
701  myEval[ID].myS = callbacks::evalS; \
702  myEval[ID].mySA = callbacks::evalSA; \
703 }
704 #define GA_INTRINSIC_METHOD_S(CLASS, ID, NAME, METHOD) { \
705  struct callbacks { \
706  static GA_Size evalS(const CLASS *o, UT_String &v) \
707  { v = o->METHOD(); return 1; } \
708  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
709  { v.append(o->METHOD()); return 1; } \
710  }; \
711  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
712  myEval[ID].myS = callbacks::evalS; \
713  myEval[ID].mySA = callbacks::evalSA; \
714 }
715 #define GA_INTRINSIC_TUPLE_S(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
716  GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
717  myEval[ID].mySA = EVAL; \
718 }
719 #define GA_INTRINSIC_TUPLE_METHOD_S(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
720  struct callbacks { \
721  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
722  { o->EVAL(v); return v.entries(); } \
723  }; \
724  GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
725  myEval[ID].mySA = callbacks::eval; \
726 }
727 #define GA_INTRINSIC_ARRAY_S(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
728  struct callbacks { \
729  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
730  static GA_Size eval(const CLASS *o, UT_StringArray &v) \
731  { \
732  const ARRAY_TYPE &array = o->METHOD(); \
733  for (exint i = 0; i < size; ++i) { v[i].append(array(i)); } \
734  return v.entries(); \
735  } \
736  }; \
737  GA_INTRINSIC_DEF_VARYING_S(ID, NAME, callbacks::tsize) \
738  myEval[ID].mySA = callbacks::eval; \
739 }
740 #define GA_INTRINSIC_VARYING_S(CLASS, ID, NAME, TSIZE, EVAL) { \
741  GA_INTRINSIC_DEF_VARYING_S(ID, NAME, TSIZE) \
742  myEval[ID].mySA = EVAL; \
743 }
744 
745 #define GA_INTRINSIC_SET_S(CLASS, ID, SETFUNC) { \
746  struct callbacks { \
747  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
748  { return SETFUNC(o, v[0]) ? 1 : 0; } \
749  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
750  { return SETFUNC(o, a(0)) ? 1 : 0; } \
751  }; \
752  myEval[ID].mySetSS = callbacks::setSS; \
753  myEval[ID].mySetSA = callbacks::setSA; \
754  myEval[ID].myReadOnly = false; \
755 }
756 #define GA_INTRINSIC_SET_METHOD_S(CLASS, ID, METHOD) { \
757  struct callbacks { \
758  static GA_Size setSS(CLASS *o, const char **v, GA_Size) \
759  { return o->METHOD(v[0]) ? 1 : 0; } \
760  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
761  { return o->METHOD(a(0)) ? 1 : 0; } \
762  }; \
763  myEval[ID].mySetSS = callbacks::setSS; \
764  myEval[ID].mySetSA = callbacks::setSA; \
765  myEval[ID].myReadOnly = false; \
766 }
767 #define GA_INTRINSIC_SET_TUPLE_S(CLASS, ID, SETFUNC) { \
768  struct callbacks { \
769  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
770  { return SETFUNC(o, a); } \
771  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
772  { \
773  UT_StringArray array; \
774  array.resize(sz); \
775  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
776  return SETFUNC(o, array); \
777  } \
778  }; \
779  myEval[ID].mySetSS = callbacks::setSS; \
780  myEval[ID].mySetSA = callbacks::setSA; \
781  myEval[ID].myReadOnly = false; \
782 }
783 #define GA_INTRINSIC_SET_TUPLE_METHOD_S(CLASS, ID, METHOD) { \
784  struct callbacks { \
785  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
786  { return o->METHOD(a); } \
787  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
788  { \
789  UT_StringArray array; \
790  array.resize(sz); \
791  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
792  return o->METHOD(array); \
793  } \
794  }; \
795  myEval[ID].mySetSS = callbacks::setSS; \
796  myEval[ID].mySetSA = callbacks::setSA; \
797  myEval[ID].myReadOnly = false; \
798 }
799 
800  // Dictionary intrinsics
801 #define GA_INTRINSIC_DEF_D(ID, NAME, TUPLESIZE) \
802  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_DICT)
803 
804 #define GA_INTRINSIC_DEF_VARYING_D(ID, NAME, TUPLESIZE_FUNC) \
805  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_DICT)
806 
807 #define GA_INTRINSIC_D(CLASS, ID, NAME, EVAL) { \
808  struct callbacks { \
809  static GA_Size evalD(const CLASS *o, UT_OptionsHolder &v) \
810  { v = EVAL(o); return 1; } \
811  static GA_Size evalDA(const CLASS *o, UT_Array<UT_OptionsHolder> &v) \
812  { v.append(EVAL(o)); return 1; } \
813  }; \
814  GA_INTRINSIC_DEF_D(ID, NAME, 1) \
815  myEval[ID].myD = callbacks::evalD; \
816  myEval[ID].myDA = callbacks::evalDA; \
817  }
818 #define GA_INTRINSIC_CONST_D(CLASS, ID, NAME, VALUE) { \
819  struct callbacks { \
820  static GA_Size evalD(const CLASS *, UT_OptionsHolder &v) \
821  { v = VALUE; return 1; } \
822  static GA_Size evalDA(const CLASS *, UT_Array<UT_OptionsHolder> &v) \
823  { v.append(VALUE); return 1; } \
824  }; \
825  GA_INTRINSIC_DEF_D(ID, NAME, 1) \
826  myEval[ID].myD = callbacks::evalD; \
827  myEval[ID].myDA = callbacks::evalDA; \
828  }
829 #define GA_INTRINSIC_METHOD_D(CLASS, ID, NAME, METHOD) { \
830  struct callbacks { \
831  static GA_Size evalD(const CLASS *o, UT_OptionsHolder &v) \
832  { v = o->METHOD(); return 1; } \
833  static GA_Size evalDA(const CLASS *o, UT_Array<UT_OptionsHolder> &v) \
834  { v.append(o->METHOD()); return 1; } \
835  }; \
836  GA_INTRINSIC_DEF_D(ID, NAME, 1) \
837  myEval[ID].myD = callbacks::evalD; \
838  myEval[ID].myDA = callbacks::evalDA; \
839  }
840 #define GA_INTRINSIC_TUPLE_D(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
841  GA_INTRINSIC_DEF_D(ID, NAME, TUPLESIZE) \
842  myEval[ID].myDA = EVAL; \
843  }
844 #define GA_INTRINSIC_TUPLE_METHOD_D(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
845  struct callbacks { \
846  static GA_Size evalDA(const CLASS *o, UT_Array<UT_OptionsHolder> &v) \
847  { o->EVAL(v); return v.entries(); } \
848  }; \
849  GA_INTRINSIC_DEF_D(ID, NAME, TUPLESIZE) \
850  myEval[ID].myDA = callbacks::eval; \
851  }
852 #define GA_INTRINSIC_ARRAY_D(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
853  struct callbacks { \
854  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
855  static GA_Size eval(const CLASS *o, UT_Array<UT_OptionsHolder> &v) \
856  { \
857  const ARRAY_TYPE &array = o->METHOD(); \
858  for (exint i = 0; i < size; ++i) { v[i].append(array(i)); } \
859  return v.entries(); \
860  } \
861  }; \
862  GA_INTRINSIC_DEF_VARYING_D(ID, NAME, callbacks::tsize) \
863  myEval[ID].myDA = callbacks::eval; \
864  }
865 #define GA_INTRINSIC_VARYING_D(CLASS, ID, NAME, TSIZE, EVAL) { \
866  GA_INTRINSIC_DEF_VARYING_D(ID, NAME, TSIZE) \
867  myEval[ID].myDA = EVAL; \
868  }
869 
870 #define GA_INTRINSIC_SET_D(CLASS, ID, SETFUNC) { \
871  struct callbacks { \
872  static GA_Size setDS(CLASS *o, const UT_OptionsHolder *v, GA_Size sz) \
873  { return SETFUNC(o, v[0]) ? 1 : 0; } \
874  static GA_Size setDA(CLASS *o, const UT_Array<UT_OptionsHolder> &a) \
875  { return SETFUNC(o, a(0)) ? 1 : 0; } \
876  }; \
877  myEval[ID].mySetDS = callbacks::setDS; \
878  myEval[ID].mySetDA = callbacks::setDA; \
879  myEval[ID].myReadOnly = false; \
880  }
881 #define GA_INTRINSIC_SET_METHOD_D(CLASS, ID, METHOD) { \
882  struct callbacks { \
883  static GA_Size setDS(CLASS *o, const UT_OptionsHolder *v, GA_Size) \
884  { return o->METHOD(v[0]) ? 1 : 0; } \
885  static GA_Size setDA(CLASS *o, const UT_Array<UT_OptionsHolder> &a) \
886  { return o->METHOD(a(0)) ? 1 : 0; } \
887  }; \
888  myEval[ID].mySetDS = callbacks::setDS; \
889  myEval[ID].mySetDA = callbacks::setDA; \
890  myEval[ID].myReadOnly = false; \
891  }
892 #define GA_INTRINSIC_SET_TUPLE_D(CLASS, ID, SETFUNC) { \
893  struct callbacks { \
894  static GA_Size setDA(CLASS *o, const UT_Array<UT_OptionsHolder> &a) \
895  { return SETFUNC(o, a); } \
896  static GA_Size setDS(CLASS *o, const UT_OptionsHolder *v, GA_Size sz) \
897  { \
898  UT_Array<UT_OptionsHolder> array; \
899  array.resize(sz); \
900  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
901  return SETFUNC(o, array); \
902  } \
903  }; \
904  myEval[ID].mySetDS = callbacks::setDS; \
905  myEval[ID].mySetDA = callbacks::setDA; \
906  myEval[ID].myReadOnly = false; \
907  }
908 #define GA_INTRINSIC_SET_TUPLE_METHOD_D(CLASS, ID, METHOD) { \
909  struct callbacks { \
910  static GA_Size setDA(CLASS *o, const UT_Array<UT_OptionsHolder> &a) \
911  { return o->METHOD(a); } \
912  static GA_Size setDS(CLASS *o, const UT_OptionsHolder *v, GA_Size sz) \
913  { \
914  UT_Array<UT_OptionsHolder> array; \
915  array.resize(sz); \
916  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
917  return o->METHOD(array); \
918  } \
919  }; \
920  myEval[ID].mySetDS = callbacks::setDS; \
921  myEval[ID].mySetDA = callbacks::setDA; \
922  myEval[ID].myReadOnly = false; \
923  }
924 #endif
925