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 <stdio.h>
19 
20 ///
21 /// The intrinsic macros help declaring intrinsic attributes for an object
22 /// (i.e. a primitive).
23 /// Typically, you'll have code like @code
24 /// enum {
25 /// ga_INTRINISIC_VAR1,
26 /// ga_INTRINISIC_VAR2,
27 /// ga_NUM_INTRINSICS
28 /// }
29 /// GA_START_INTRINSIC_DEF(ClassName, ga_NUM_INTRINSICS)
30 /// GA_INTRINSIC_I(ClassName, ga_INTRINSIC_VAR1, "name1",
31 /// EvaluationCallback)
32 /// GA_INTRINSIC_VARYING_F(ClassName, ga_INTRINISIC_VAR2, "name2",
33 /// TupleSizeMethod,
34 /// EvaluationCallback)
35 /// GA_END_INTRINSIC_DEF(ClassName, BaseClassName)
36 /// @endcode
37 ///
38 /// There are several ways to declare intrinsic access methods:
39 ///
40 /// GA_INTRINSIC_I(ClassName, Enum, Name, Callback)
41 /// - Tuple size is fixed at 1
42 /// - Callback returns value:
43 /// static exint callback(const ClassName *obj);
44 /// static fpreal callback(const ClassName *obj);
45 /// static const char *callback(const ClassName *obj);
46 ///
47 /// GA_INTRINSIC_CONST_I(ClassName, Enum, Name, Value)
48 /// - Tuple size is fixed at 1
49 /// - int/float/(const char *) Value is specified
50 ///
51 /// GA_INTRINSIC_METHOD_I(ClassName, Enum, Name, MethodName)
52 /// - Tuple size is fixed at 1
53 /// - MethodName specifies a public method on ClassName which returns the
54 /// value.
55 /// exint ClassName::MethodName() const;
56 /// fpreal ClassName::MethodName() const;
57 /// const char *ClassName::MethodName() const;
58 ///
59 /// GA_INTRINSIC_TUPLE_I(ClassName, Enum, Name, TUPLE_SIZE, Callback)
60 /// - TUPLE_SIZE is a constant value
61 /// - Callback fills value (returning number of items set):
62 /// static int callback(const ClassName *obj, int64 *v, GA_Size sz);
63 /// static int callback(const ClassName *obj, fpreal64 *v, GA_Size sz);
64 /// static void callback(const ClassName *obj, UT_StringArray &v);
65 ///
66 /// GA_INTRINSIC_TUPLE_METHOD_I(ClassName, Enum, Name, TUPLE_SIZE, MethodName)
67 /// - TUPLE_SIZE is a constant value
68 /// - MethodName is a public method on ClassName which fills the value,
69 /// returning the number of items set:
70 /// int ClassName::MethodName(int64 *v, GA_Size sz) const;
71 /// int ClassName::MethodName(fpreal64 *v, GA_Size sz) const;
72 /// void ClassName::MethodName(UT_StringArray &v, GA_Size sz) const;
73 ///
74 /// GA_INTRINSIC_ARRAY_I(ClassName, Enum, Name, ArrayType, MethodName)
75 /// - ArrayType specifies an array which has:
76 /// - entries() const: Return number of elements in the array
77 /// - operator()(exint i) const: Returning the element of the array
78 /// - MethodName is a public method on ClassName which returns the a const
79 /// reference to an ArrayType object.
80 /// const ArrayType &ClassName::MethodName() const
81 ///
82 /// GA_INTRINSIC_VARYING_I(ClassName, Enum, Name, TupleSizeCallback, Callback)
83 /// - TupleSizeCallback is a function returning the tuple size
84 /// static int tuplesizecallback(const ClassName *obj)
85 /// - Callback fills value, returning number of items set:
86 /// static int callback(const ClassName *obj, int64 *v, GA_Size sz);
87 /// static int callback(const ClassName *obj, fpreal64 *v, GA_Size sz);
88 /// static int callback(const ClassName *obj, UT_StringArray &v);
89 ///
90 /// For setting values, there are similar macros. The tuple size and name are
91 /// usually defined by the evaluation macros. If there is no "get" method, you
92 /// can still declare the intrinsic using:
93 /// GA_INTRINSIC_DEF_I(Enum, Name, TupleSize)
94 /// GA_INTRINSIC_DEF_VARYING_I(Enum, Name, TupleSizeFunc)
95 ///
96 /// GA_INTRINSIC_SET_I(ClassName, Enum, Callback)
97 /// - Callback specifies a static function which sets the value, returning
98 /// false if unable to set (i.e. invalid value). The function can take a
99 /// 32/64 bit value.
100 /// static bool set(ClassName *o, exint v);
101 /// static bool set(ClassName *o, fpreal v);
102 /// static bool set(ClassName *o, const char *v);
103 ///
104 /// GA_INTRINSIC_SET_METHOD_I(ClassName, Enum, MethodName)
105 /// - MethodName specifies a public method on ClassName which sets the
106 /// value. The method can take 32/64 bit values
107 /// bool ClassName::MethodName(exint value);
108 /// bool ClassName::MethodName(fpreal value);
109 ///
110 /// GA_INTRINSIC_SET_TUPLE_I(ClassName, Enum, Callback)
111 /// - Callback specifies a static function which sets the value, returning
112 /// the number of values set.
113 /// static int set(ClassName *o, const int64 *v, int tuple_size);
114 /// static int set(ClassName *o, const fpreal64 *v, int tuple_size);
115 /// static int set(ClassName *o, const UT_StringArray &v);
116 ///
117 /// GA_INTRINSIC_SET_TUPLE_METHOD_I(ClassName, Enum, Callback)
118 /// - Callback specifies a static function which sets the value, returning
119 /// the number of values set.
120 /// int ClassName::set(const int64 *v, int tuple_size);
121 /// int ClassName::set(const fpreal64 *v, int tuple_size);
122 /// int ClassName::set(const UT_StringArray &v);
123 
124 #define GA_START_INTRINSIC_DEF(CLASS, NUM_INTRINSICS) \
125 namespace \
126 { \
127  class _ga_intrinsicEvaluator##CLASS \
128  { \
129  public: \
130  typedef GA_Size (*cbTupleSize)(const CLASS *obj); \
131  typedef GA_Size (*cbEvalI)(const CLASS *obj, int64 *v, GA_Size size); \
132  typedef GA_Size (*cbEvalF)(const CLASS *obj, fpreal64 *v, GA_Size size); \
133  typedef GA_Size (*cbEvalS)(const CLASS *obj, UT_String &s); \
134  typedef GA_Size (*cbEvalSA)(const CLASS *obj, UT_StringArray &s); \
135  typedef GA_Size (*cbSetI)(CLASS *obj, const int64 *v, GA_Size size); \
136  typedef GA_Size (*cbSetF)(CLASS *obj, const fpreal64 *v, GA_Size size); \
137  typedef GA_Size (*cbSetS)(CLASS *obj, const char **v, GA_Size size); \
138  typedef GA_Size (*cbSetSA)(CLASS *obj, const UT_StringArray &v); \
139  static GA_Size failTS(const CLASS *) { return 0; } \
140  static GA_Size failI(const CLASS *, int64 *, GA_Size) { UT_ASSERT(0); return 0; } \
141  static GA_Size failF(const CLASS *, fpreal64 *, GA_Size) { UT_ASSERT(0); return 0; } \
142  static GA_Size failS(const CLASS *, UT_String &) { UT_ASSERT(0); return 0; } \
143  static GA_Size failSA(const CLASS *, UT_StringArray &) { UT_ASSERT(0); return 0; } \
144  static GA_Size failI(CLASS *, const int64 *, GA_Size) { UT_ASSERT(0); return 0; } \
145  static GA_Size failF(CLASS *, const fpreal64 *, GA_Size) { UT_ASSERT(0); return 0; } \
146  static GA_Size failS(CLASS *, const char **, GA_Size) { UT_ASSERT(0); return 0; } \
147  static GA_Size failSA(CLASS *, const UT_StringArray &) { UT_ASSERT(0); return 0; } \
148  class Eval \
149  { \
150  public: \
151  Eval() \
152  : myId(-1) \
153  , myName(NULL) \
154  , myOptions(NULL) \
155  , myStore(GA_STORECLASS_INVALID) \
156  , myTupleSizeCB(failTS) \
157  , myTupleSize(-1) \
158  , myI(failI) \
159  , myF(failF) \
160  , myS(failS) \
161  , mySA(failSA) \
162  , mySetI(failI) \
163  , mySetF(failF) \
164  , mySetSS(failS) \
165  , mySetSA(failSA) \
166  , myReadOnly(true) \
167  { \
168  } \
169  GA_Size getTupleSize(const CLASS *o) const \
170  { \
171  if (myTupleSize > 0) return myTupleSize; \
172  return myTupleSizeCB(o); \
173  } \
174  void dump() { \
175  fprintf(stderr, "Intrinsic[%d] := {\n", myId); \
176  fprintf(stderr, " 'name' : '%s'\n", myName); \
177  fprintf(stderr, " 'tuple' : %d\n", (int)myTupleSize); \
178  fprintf(stderr, " 'storage' : %s\n", GAstorageClass(myStore));\
179  fprintf(stderr, " 'ro' : %d\n", myReadOnly); \
180  fprintf(stderr, " 'tuple()' : %p\n", myTupleSizeCB); \
181  fprintf(stderr, " 'options' : %p\n", myOptions); \
182  fprintf(stderr, " 'I()' : %p\n", myI); \
183  fprintf(stderr, " 'F()' : %p\n", myF); \
184  fprintf(stderr, " 'S()' : %p\n", myS); \
185  fprintf(stderr, " 'SA()' : %p\n", mySA); \
186  fprintf(stderr, " 'setI()' : %p\n", mySetI); \
187  fprintf(stderr, " 'setF()' : %p\n", mySetF); \
188  fprintf(stderr, " 'setSS()' : %p\n", mySetSS); \
189  fprintf(stderr, " 'setSA()' : %p\n", mySetSA); \
190  } \
191  bool valid(int index) const \
192  { \
193  if (myName && myId >= 0 && myStore != GA_STORECLASS_INVALID \
194  && (myTupleSize > 0 || myTupleSizeCB) \
195  && (myI || myF || myS || mySA)) \
196  return true; \
197  fprintf(stderr, "Warning: missing intrinsic for %s[%d]\n", \
198  #CLASS, index); \
199  return false; \
200  } \
201  cbTupleSize myTupleSizeCB; \
202  cbEvalI myI; \
203  cbEvalF myF; \
204  cbEvalS myS; \
205  cbEvalSA mySA; \
206  cbSetI mySetI; \
207  cbSetF mySetF; \
208  cbSetS mySetSS; \
209  cbSetSA mySetSA; \
210  const char *myName; \
211  const UT_Options *myOptions; \
212  GA_Size myTupleSize; \
213  int myId; \
214  GA_StorageClass myStore; \
215  bool myReadOnly; \
216  }; \
217  Eval myEval[NUM_INTRINSICS]; \
218  int entries() const { return NUM_INTRINSICS; } \
219  bool valid(int i) const { return myEval[i].valid(i); } \
220  GA_Size getTupleSize(int i, const CLASS *o) const \
221  { return myEval[i].getTupleSize(o); } \
222  GA_Size evalI(int i, const CLASS *o, int64 *v, GA_Size n) const \
223  { return myEval[i].myI(o, v, n); } \
224  GA_Size evalF(int i, const CLASS *o, fpreal64 *v, GA_Size n) const \
225  { return myEval[i].myF(o, v, n); } \
226  GA_Size evalS(int i, const CLASS *o, UT_String &v) const \
227  { return myEval[i].myS(o, v); } \
228  GA_Size evalSA(int i, const CLASS *o, UT_StringArray &v) const \
229  { return myEval[i].mySA(o, v); } \
230  GA_Size setI(int i, CLASS *o, const int64 *v, GA_Size n) const \
231  { return myEval[i].mySetI(o, v, n); } \
232  GA_Size setF(int i, CLASS *o, const fpreal64 *v, GA_Size n) const \
233  { return myEval[i].mySetF(o, v, n); } \
234  GA_Size setSS(int i, CLASS *o, const char **v, GA_Size n) const \
235  { return myEval[i].mySetSS(o, v, n); } \
236  GA_Size setSA(int i, CLASS *o, const UT_StringArray &v) const \
237  { return myEval[i].mySetSA(o, v); } \
238  GA_StorageClass getStorageClass(int i) const \
239  { return myEval[i].myStore; } \
240  const char *getName(int i) const { return myEval[i].myName; } \
241  int getId(int i) const { return myEval[i].myId; } \
242  bool getReadOnly(int i) const { return myEval[i].myReadOnly; } \
243  const UT_Options *getOptions(int i) const \
244  { return myEval[i].myOptions; } \
245  _ga_intrinsicEvaluator##CLASS() {
246 
247 #define GA_END_INTRINSIC_DEF(CLASS, BASECLASS) \
248  } \
249  }; \
250  static GA_IntrinsicDef _theIntrinsics##CLASS; \
251  static _ga_intrinsicEvaluator##CLASS _theEval##CLASS; \
252  } \
253  GA_IntrinsicManager::Registrar \
254  CLASS::registerIntrinsics(GA_PrimitiveDefinition &defn) \
255  { \
256  GA_IntrinsicManager::Registrar r(BASECLASS::registerIntrinsics(defn)); \
257  if (r.start(_theIntrinsics##CLASS)) \
258  { \
259  for (int i = 0; i < _theEval##CLASS.entries(); ++i) \
260  { \
261  UT_ASSERT(_theEval##CLASS.getName(i)); \
262  if (_theEval##CLASS.valid(i)) \
263  { \
264  r.addAttribute(_theEval##CLASS.getStorageClass(i), \
265  _theEval##CLASS.getName(i), \
266  _theEval##CLASS.getId(i), \
267  _theEval##CLASS.getReadOnly(i), \
268  _theEval##CLASS.getOptions(i)); \
269  } \
270  } \
271  } \
272  return r; \
273  } \
274  GA_Size \
275  CLASS::localIntrinsicTupleSize(const GA_IntrinsicEval &eval) const \
276  { \
277  int id = eval.getUserId(_theIntrinsics##CLASS); \
278  if (id >= 0 && id < _theEval##CLASS.entries()) \
279  return _theEval##CLASS.getTupleSize(id, this); \
280  return BASECLASS::localIntrinsicTupleSize(eval); \
281  } \
282  GA_Size \
283  CLASS::localGetIntrinsicI(const GA_IntrinsicEval &eval, \
284  int64 *v, GA_Size size) const \
285  { \
286  int id = eval.getUserId(_theIntrinsics##CLASS); \
287  if (id >= 0 && id < _theEval##CLASS.entries()) \
288  return _theEval##CLASS.evalI(id, this, v, size); \
289  return BASECLASS::localGetIntrinsicI(eval, v, size); \
290  } \
291  GA_Size \
292  CLASS::localGetIntrinsicF(const GA_IntrinsicEval &eval, \
293  fpreal64 *v, GA_Size size) const \
294  { \
295  int id = eval.getUserId(_theIntrinsics##CLASS); \
296  if (id >= 0 && id < _theEval##CLASS.entries()) \
297  return _theEval##CLASS.evalF(id, this, v, size); \
298  return BASECLASS::localGetIntrinsicF(eval, v, size); \
299  } \
300  GA_Size \
301  CLASS::localGetIntrinsicS(const GA_IntrinsicEval &eval, \
302  UT_String &v) const \
303  { \
304  int id = eval.getUserId(_theIntrinsics##CLASS); \
305  if (id >= 0 && id < _theEval##CLASS.entries()) \
306  return _theEval##CLASS.evalS(id, this, v); \
307  return BASECLASS::localGetIntrinsicS(eval, v); \
308  } \
309  GA_Size \
310  CLASS::localGetIntrinsicSA(const GA_IntrinsicEval &eval, \
311  UT_StringArray &v) const \
312  { \
313  int id = eval.getUserId(_theIntrinsics##CLASS); \
314  if (id >= 0 && id < _theEval##CLASS.entries()) \
315  return _theEval##CLASS.evalSA(id, this, v); \
316  return BASECLASS::localGetIntrinsicSA(eval, v); \
317  } \
318  GA_Size \
319  CLASS::localSetIntrinsicI(const GA_IntrinsicEval &eval, \
320  const int64 *v, GA_Size size) \
321  { \
322  int id = eval.getUserId(_theIntrinsics##CLASS); \
323  if (id >= 0 && id < _theEval##CLASS.entries()) \
324  return _theEval##CLASS.setI(id, this, v, size); \
325  return BASECLASS::localSetIntrinsicI(eval, v, size); \
326  } \
327  GA_Size \
328  CLASS::localSetIntrinsicF(const GA_IntrinsicEval &eval, \
329  const fpreal64 *v, GA_Size size) \
330  { \
331  int id = eval.getUserId(_theIntrinsics##CLASS); \
332  if (id >= 0 && id < _theEval##CLASS.entries()) \
333  return _theEval##CLASS.setF(id, this, v, size); \
334  return BASECLASS::localSetIntrinsicF(eval, v, size); \
335  } \
336  GA_Size \
337  CLASS::localSetIntrinsicSS(const GA_IntrinsicEval &eval, \
338  const char **v, GA_Size size) \
339  { \
340  int id = eval.getUserId(_theIntrinsics##CLASS); \
341  if (id >= 0 && id < _theEval##CLASS.entries()) \
342  return _theEval##CLASS.setSS(id, this, v, size); \
343  return BASECLASS::localSetIntrinsicSS(eval, v, size); \
344  } \
345  GA_Size \
346  CLASS::localSetIntrinsicSA(const GA_IntrinsicEval &eval, \
347  const UT_StringArray &v) \
348  { \
349  int id = eval.getUserId(_theIntrinsics##CLASS); \
350  if (id >= 0 && id < _theEval##CLASS.entries()) \
351  return _theEval##CLASS.setSA(id, this, v); \
352  return BASECLASS::localSetIntrinsicSA(eval, v); \
353  }
354 
355 // ----------- Intrinsic definition macros start here ------------
356 #define GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, STORAGE) \
357  myEval[ID].myId = ID; \
358  myEval[ID].myName = NAME; \
359  myEval[ID].myStore = STORAGE; \
360  myEval[ID].myTupleSize = TUPLESIZE;
361 #define GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, STORAGE) \
362  myEval[ID].myId = ID; \
363  myEval[ID].myName = NAME; \
364  myEval[ID].myStore = STORAGE; \
365  myEval[ID].myTupleSizeCB = TUPLESIZE_FUNC;
366 
367 // Set UT_Options bound to intrinsic definition. You might consider storing
368 // information about attribute in the options (i.e. "type":GA_TypeInfo). This
369 // is totally optional.
370 #define GA_INTRINSIC_OPTIONS(ID, OPTIONS) \
371  myEval[ID].myOptions = &OPTIONS;
372 
373 // Integer intrinsics
374 #define GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
375  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_INT)
376 
377 #define GA_INTRINSIC_DEF_VARYING_I(ID, NAME, TUPLESIZE_FUNC) \
378  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_INT)
379 
380 #define GA_INTRINSIC_I(CLASS, ID, NAME, EVAL) { \
381  struct callbacks { \
382  static GA_Size eval(const CLASS *o, int64 *v, GA_Size) \
383  { v[0] = EVAL(o); return 1; } \
384  }; \
385  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
386  myEval[ID].myI = callbacks::eval; \
387  }
388 #define GA_INTRINSIC_CONST_I(CLASS, ID, NAME, VALUE) { \
389  struct callbacks { \
390  static GA_Size eval(const CLASS *, int64 *v, GA_Size) \
391  { v[0] = VALUE; return 1; } \
392  }; \
393  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
394  myEval[ID].myI = callbacks::eval; \
395  }
396 #define GA_INTRINSIC_METHOD_I(CLASS, ID, NAME, METHOD) { \
397  struct callbacks { \
398  static GA_Size eval(const CLASS *o, int64 *v, GA_Size) \
399  { v[0] = o->METHOD(); return 1; } \
400  }; \
401  GA_INTRINSIC_DEF_I(ID, NAME, 1) \
402  myEval[ID].myI = callbacks::eval; \
403  }
404 #define GA_INTRINSIC_TUPLE_I(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
405  GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
406  myEval[ID].myI = EVAL; \
407  }
408 #define GA_INTRINSIC_TUPLE_METHOD_I(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
409  struct callbacks { \
410  static GA_Size eval(const CLASS *o, int64 *v, GA_Size sz) \
411  { return o->EVAL(v, sz); } \
412  }; \
413  GA_INTRINSIC_DEF_I(ID, NAME, TUPLESIZE) \
414  myEval[ID].myI = callbacks::eval; \
415  }
416 #define GA_INTRINSIC_ARRAY_I(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
417  struct callbacks { \
418  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
419  static GA_Size eval(const CLASS *o, int64 *v, GA_Size size) \
420  { \
421  const ARRAY_TYPE &array = o->METHOD(); \
422  size = SYSmin(size, array.entries()); \
423  for (exint i = 0; i < size; ++i) { v[i] = array(i); } \
424  return size; \
425  } \
426  }; \
427  GA_INTRINSIC_DEF_VARYING_I(ID, NAME, callbacks::tsize) \
428  myEval[ID].myI = callbacks::eval; \
429  }
430 #define GA_INTRINSIC_VARYING_I(CLASS, ID, NAME, TSIZE, EVAL) { \
431  GA_INTRINSIC_DEF_VARYING_I(ID, NAME, TSIZE) \
432  myEval[ID].myI = EVAL; \
433  }
434 
435 #define GA_INTRINSIC_SET_I(CLASS, ID, SETFUNC) { \
436  struct callbacks { \
437  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
438  { return SETFUNC(o, v[0]) ? 1 : 0; } \
439  }; \
440  myEval[ID].mySetI = callbacks::setFunc; \
441  myEval[ID].myReadOnly = false; \
442  }
443 #define GA_INTRINSIC_SET_METHOD_I(CLASS, ID, METHOD) { \
444  struct callbacks { \
445  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
446  { return o->METHOD(v[0]) ? 1 : 0; } \
447  }; \
448  myEval[ID].mySetI = callbacks::setFunc; \
449  myEval[ID].myReadOnly = false; \
450  }
451 #define GA_INTRINSIC_SET_TUPLE_I(CLASS, ID, SETFUNC) { \
452  struct callbacks { \
453  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
454  { return SETFUNC(o, v, sz); } \
455  }; \
456  myEval[ID].mySetI = callbacks::setFunc; \
457  myEval[ID].myReadOnly = false; \
458  }
459 #define GA_INTRINSIC_SET_TUPLE_METHOD_I(CLASS, ID, METHOD) { \
460  struct callbacks { \
461  static GA_Size setFunc(CLASS *o, const int64 *v, GA_Size sz) \
462  { return o->METHOD(v[0], sz); } \
463  }; \
464  myEval[ID].mySetI = callbacks::setFunc; \
465  myEval[ID].myReadOnly = false; \
466  }
467 
468 // Float intrinsics
469 #define GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
470  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_FLOAT)
471 
472 #define GA_INTRINSIC_DEF_VARYING_F(ID, NAME, TUPLESIZE_FUNC) \
473  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_FLOAT)
474 
475 #define GA_INTRINSIC_F(CLASS, ID, NAME, EVAL) { \
476  struct callbacks { \
477  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size) \
478  { v[0] = EVAL(o); return 1; } \
479  }; \
480  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
481  myEval[ID].myF = callbacks::eval; \
482  }
483 #define GA_INTRINSIC_CONST_F(CLASS, ID, NAME, VALUE) { \
484  struct callbacks { \
485  static GA_Size eval(const CLASS *, fpreal64 *v, GA_Size) \
486  { v[0] = VALUE; return 1; } \
487  }; \
488  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
489  myEval[ID].myF = callbacks::eval; \
490  }
491 #define GA_INTRINSIC_METHOD_F(CLASS, ID, NAME, METHOD) { \
492  struct callbacks { \
493  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size) \
494  { v[0] = o->METHOD(); return 1; } \
495  }; \
496  GA_INTRINSIC_DEF_F(ID, NAME, 1) \
497  myEval[ID].myF = callbacks::eval; \
498  }
499 #define GA_INTRINSIC_TUPLE_F(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
500  GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
501  myEval[ID].myF = EVAL; \
502  }
503 #define GA_INTRINSIC_TUPLE_METHOD_F(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
504  struct callbacks { \
505  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size sz) \
506  { return o->EVAL(v, sz); } \
507  }; \
508  GA_INTRINSIC_DEF_F(ID, NAME, TUPLESIZE) \
509  myEval[ID].myF = callbacks::eval; \
510  }
511 #define GA_INTRINSIC_ARRAY_F(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
512  struct callbacks { \
513  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
514  static GA_Size eval(const CLASS *o, fpreal64 *v, GA_Size size) \
515  { \
516  const ARRAY_TYPE &array = o->METHOD(); \
517  size = SYSmin(size, array.entries()); \
518  for (exint i = 0; i < size; ++i) { v[i] = array(i); } \
519  return size; \
520  } \
521  }; \
522  GA_INTRINSIC_DEF_VARYING_F(ID, NAME, callbacks::tsize) \
523  myEval[ID].myF = callbacks::eval; \
524  }
525 #define GA_INTRINSIC_VARYING_F(CLASS, ID, NAME, TSIZE, EVAL) { \
526  GA_INTRINSIC_DEF_VARYING_F(ID, NAME, TSIZE) \
527  myEval[ID].myF = EVAL; \
528  }
529 
530 #define GA_INTRINSIC_SET_F(CLASS, ID, SETFUNC) { \
531  struct callbacks { \
532  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
533  { SETFUNC(o, v[0]); return 1; } \
534  }; \
535  myEval[ID].mySetF = callbacks::setFunc; \
536  myEval[ID].myReadOnly = false; \
537  }
538 #define GA_INTRINSIC_SET_METHOD_F(CLASS, ID, METHOD) { \
539  struct callbacks { \
540  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
541  { o->METHOD(v[0]); return 1; } \
542  }; \
543  myEval[ID].mySetF = callbacks::setFunc; \
544  myEval[ID].myReadOnly = false; \
545  }
546 #define GA_INTRINSIC_SET_TUPLE_F(CLASS, ID, SETFUNC) { \
547  struct callbacks { \
548  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
549  { return SETFUNC(o, v, sz); } \
550  }; \
551  myEval[ID].mySetF = callbacks::setFunc; \
552  myEval[ID].myReadOnly = false; \
553  }
554 #define GA_INTRINSIC_SET_TUPLE_METHOD_F(CLASS, ID, METHOD) { \
555  struct callbacks { \
556  static GA_Size setFunc(CLASS *o, const fpreal64 *v, GA_Size sz) \
557  { return o->METHOD(v[0], sz); } \
558  }; \
559  myEval[ID].mySetF = callbacks::setFunc; \
560  myEval[ID].myReadOnly = false; \
561  }
562 
563 // String intrinsics
564 #define GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
565  GA_INTRINSIC_DEF(ID, NAME, TUPLESIZE, GA_STORECLASS_STRING)
566 
567 #define GA_INTRINSIC_DEF_VARYING_S(ID, NAME, TUPLESIZE_FUNC) \
568  GA_INTRINSIC_DEF_VARYING(ID, NAME, TUPLESIZE_FUNC, GA_STORECLASS_STRING)
569 
570 #define GA_INTRINSIC_S(CLASS, ID, NAME, EVAL) { \
571  struct callbacks { \
572  static GA_Size evalS(const CLASS *o, UT_String &v) \
573  { v = EVAL(o); return 1; } \
574  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
575  { v.append(EVAL(o)); return 1; } \
576  }; \
577  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
578  myEval[ID].myS = callbacks::evalS; \
579  myEval[ID].mySA = callbacks::evalSA; \
580  }
581 #define GA_INTRINSIC_CONST_S(CLASS, ID, NAME, VALUE) { \
582  struct callbacks { \
583  static GA_Size evalS(const CLASS *, UT_String &v) \
584  { v = VALUE; return 1; } \
585  static GA_Size evalSA(const CLASS *, UT_StringArray &v) \
586  { v.append(VALUE); return 1; } \
587  }; \
588  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
589  myEval[ID].myS = callbacks::evalS; \
590  myEval[ID].mySA = callbacks::evalSA; \
591  }
592 #define GA_INTRINSIC_METHOD_S(CLASS, ID, NAME, METHOD) { \
593  struct callbacks { \
594  static GA_Size evalS(const CLASS *o, UT_String &v) \
595  { v = o->METHOD(); return 1; } \
596  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
597  { v.append(o->METHOD()); return 1; } \
598  }; \
599  GA_INTRINSIC_DEF_S(ID, NAME, 1) \
600  myEval[ID].myS = callbacks::evalS; \
601  myEval[ID].mySA = callbacks::evalSA; \
602  }
603 #define GA_INTRINSIC_TUPLE_S(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
604  GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
605  myEval[ID].mySA = EVAL; \
606  }
607 #define GA_INTRINSIC_TUPLE_METHOD_S(CLASS, ID, NAME, TUPLESIZE, EVAL) { \
608  struct callbacks { \
609  static GA_Size evalSA(const CLASS *o, UT_StringArray &v) \
610  { o->EVAL(v); return v.entries(); } \
611  }; \
612  GA_INTRINSIC_DEF_S(ID, NAME, TUPLESIZE) \
613  myEval[ID].mySA = callbacks::eval; \
614  }
615 #define GA_INTRINSIC_ARRAY_S(CLASS, ID, NAME, ARRAY_TYPE, METHOD) { \
616  struct callbacks { \
617  static GA_Size tsize(const CLASS *o) { return o->METHOD().entries(); } \
618  static GA_Size eval(const CLASS *o, UT_StringArray &v) \
619  { \
620  const ARRAY_TYPE &array = o->METHOD(); \
621  for (exint i = 0; i < size; ++i) { v[i].append(array(i)); } \
622  return v.entries(); \
623  } \
624  }; \
625  GA_INTRINSIC_DEF_VARYING_S(ID, NAME, callbacks::tsize) \
626  myEval[ID].mySA = callbacks::eval; \
627  }
628 #define GA_INTRINSIC_VARYING_S(CLASS, ID, NAME, TSIZE, EVAL) { \
629  GA_INTRINSIC_DEF_VARYING_S(ID, NAME, TSIZE) \
630  myEval[ID].mySA = EVAL; \
631  }
632 
633 #define GA_INTRINSIC_SET_S(CLASS, ID, SETFUNC) { \
634  struct callbacks { \
635  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
636  { return SETFUNC(o, v[0]) ? 1 : 0; } \
637  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
638  { return SETFUNC(o, a(0)) ? 1 : 0; } \
639  }; \
640  myEval[ID].mySetSS = callbacks::setSS; \
641  myEval[ID].mySetSA = callbacks::setSA; \
642  myEval[ID].myReadOnly = false; \
643  }
644 #define GA_INTRINSIC_SET_METHOD_S(CLASS, ID, METHOD) { \
645  struct callbacks { \
646  static GA_Size setSS(CLASS *o, const char **v, GA_Size) \
647  { return o->METHOD(v[0]) ? 1 : 0; } \
648  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
649  { return o->METHOD(a(0)) ? 1 : 0; } \
650  }; \
651  myEval[ID].mySetSS = callbacks::setSS; \
652  myEval[ID].mySetSA = callbacks::setSA; \
653  myEval[ID].myReadOnly = false; \
654  }
655 #define GA_INTRINSIC_SET_TUPLE_S(CLASS, ID, SETFUNC) { \
656  struct callbacks { \
657  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
658  { return SETFUNC(o, a); } \
659  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
660  { \
661  UT_StringArray array; \
662  array.resize(sz); \
663  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
664  return SETFUNC(o, array); \
665  } \
666  }; \
667  myEval[ID].mySetSS = callbacks::setSS; \
668  myEval[ID].mySetSA = callbacks::setSA; \
669  myEval[ID].myReadOnly = false; \
670  }
671 #define GA_INTRINSIC_SET_TUPLE_METHOD_S(CLASS, ID, METHOD) { \
672  struct callbacks { \
673  static GA_Size setSA(CLASS *o, const UT_StringArray &a) \
674  { return o->METHOD(a); } \
675  static GA_Size setSS(CLASS *o, const char **v, GA_Size sz) \
676  { \
677  UT_StringArray array; \
678  array.resize(sz); \
679  for (exint i = 0; i < sz; ++i) array(i) = v[i]; \
680  return o->METHOD(array); \
681  } \
682  }; \
683  myEval[ID].mySetSS = callbacks::setSS; \
684  myEval[ID].mySetSA = callbacks::setSA; \
685  myEval[ID].myReadOnly = false; \
686  }
687 
688 #endif
689