Beast - Music Synthesizer and Composer  0.11.1+10.g2da35
sficxx.hh
Go to the documentation of this file.
1  // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
2 #ifndef __SFI_CXX_H__
3 #define __SFI_CXX_H__
4 #include <sfi/sfi.hh>
5 #include <string>
6 #include <string.h>
7 #include <new>
8 
10 namespace Sfi {
11 typedef SfiBool Bool; // FIXME: use bool instead?
12 typedef SfiInt Int;
13 typedef SfiNum Num;
14 typedef SfiReal Real;
15 
16 class SfiString {
17  char *cstring;
18  int cmp (const char *ostring) const
19  {
20  if (cstring && ostring)
21  return strcmp (cstring, ostring);
22  else if (cstring)
23  return +SFI_MAXINT;
24  else
25  return ostring ? SFI_MININT : 0;
26  }
27 public:
28  SfiString()
29  {
30  cstring = g_strdup ("");
31  }
32  SfiString (const SfiString &s)
33  {
34  cstring = g_strdup (s.cstring);
35  }
36  SfiString (const std::string &s)
37  {
38  cstring = g_strdup (s.c_str());
39  }
40  SfiString (const char *cstr)
41  {
42  cstring = g_strdup (cstr ? cstr : "");
43  }
44  operator std::string () const { return cstring; }
45  SfiString& operator= (const std::string &s)
46  {
47  g_free (cstring);
48  cstring = g_strdup (s.c_str());
49  return *this;
50  }
51  SfiString& operator= (const gchar *cstr)
52  {
53  if (cstr != cstring)
54  {
55  g_free (cstring);
56  cstring = g_strdup (cstr ? cstr : "");
57  }
58  return *this;
59  }
60  SfiString& operator= (const SfiString &s)
61  {
62  if (s.cstring != cstring)
63  {
64  g_free (cstring);
65  cstring = g_strdup (s.cstring);
66  }
67  return *this;
68  }
69  const char* c_str() const
70  {
71  return cstring;
72  }
73  SfiString& operator+= (const gchar *cstr)
74  {
75  char *old = cstring;
76  cstring = g_strconcat (old ? old : "", cstr, NULL);
77  g_free (old);
78  return *this;
79  }
80  SfiString& operator+= (const SfiString &src)
81  {
82  char *old = cstring;
83  cstring = g_strconcat (old ? old : "", src.cstring, NULL);
84  g_free (old);
85  return *this;
86  }
87  SfiString& operator+= (const std::string &src)
88  {
89  char *old = cstring;
90  cstring = g_strconcat (old ? old : "", src.c_str(), NULL);
91  g_free (old);
92  return *this;
93  }
94  SfiString operator+ (const gchar *cstr)
95  {
96  return SfiString (cstring) += cstr;
97  }
98  SfiString operator+ (const SfiString &src)
99  {
100  return SfiString (cstring) += src;
101  }
102  SfiString operator+ (const std::string &src)
103  {
104  return SfiString (cstring) += src;
105  }
106  bool operator< (const char *src) const { return cmp (src) < 0; }
107  bool operator<= (const char *src) const { return cmp (src) <= 0; }
108  bool operator> (const char *src) const { return cmp (src) > 0; }
109  bool operator>= (const char *src) const { return cmp (src) >= 0; }
110  bool operator!= (const char *src) const { return cmp (src) != 0; }
111  bool operator== (const char *src) const { return cmp (src) == 0; }
112  bool operator< (const SfiString &s) const { return cmp (s.cstring) < 0; }
113  bool operator<= (const SfiString &s) const { return cmp (s.cstring) <= 0; }
114  bool operator> (const SfiString &s) const { return cmp (s.cstring) > 0; }
115  bool operator>= (const SfiString &s) const { return cmp (s.cstring) >= 0; }
116  bool operator!= (const SfiString &s) const { return cmp (s.cstring) != 0; }
117  bool operator== (const SfiString &s) const { return cmp (s.cstring) == 0; }
118  bool operator< (const std::string &s) const { return cmp (s.c_str()) < 0; }
119  bool operator<= (const std::string &s) const { return cmp (s.c_str()) <= 0; }
120  bool operator> (const std::string &s) const { return cmp (s.c_str()) > 0; }
121  bool operator>= (const std::string &s) const { return cmp (s.c_str()) >= 0; }
122  bool operator!= (const std::string &s) const { return cmp (s.c_str()) != 0; }
123  bool operator== (const std::string &s) const { return cmp (s.c_str()) == 0; }
124  unsigned int length()
125  {
126  return cstring ? strlen (cstring) : 0;
127  }
128  ~SfiString()
129  {
130  g_free (cstring);
131  }
132  /* provide GValue accessors */
133  static SfiString value_get_string (const GValue *value)
134  {
135  return sfi_value_get_string (value);
136  }
137  static void value_set_string (GValue *value, const SfiString& str)
138  {
139  sfi_value_set_string (value, str.c_str());
140  }
141 };
142 
143 struct GNewable {
144  gpointer operator new (size_t s)
145  {
146  return g_malloc0 (s);
147  }
148  void operator delete (gpointer mem)
149  {
150  g_free (mem);
151  }
152  gpointer operator new[] (size_t s)
153  {
154  return g_malloc0 (s);
155  }
156  void operator delete[] (gpointer mem)
157  {
158  g_free (mem);
159  }
160 };
161 
162 typedef enum {
163  INIT_NULL,
164  INIT_EMPTY,
165  INIT_DEFAULT,
166 } InitializationType;
167 
168 template<typename Type>
170  Type *record;
171  typedef Type BoxedType;
172 public:
173  RecordHandle (InitializationType t = INIT_NULL)
174  {
175  record = NULL;
176  if (t == INIT_DEFAULT || t == INIT_EMPTY)
177  record = new Type();
178  }
179  RecordHandle (const RecordHandle &rh)
180  {
181  if (rh.record)
182  record = new Type (*rh.record);
183  else
184  record = NULL;
185  }
186  RecordHandle (const Type &rec)
187  {
188  record = new Type (rec);
189  }
190  RecordHandle& operator= (const Type &rec)
191  {
192  if (record != &rec)
193  {
194  delete record;
195  record = new Type (rec);
196  }
197  return *this;
198  }
199  void set_boxed (Type *rec)
200  {
201  delete record;
202  if (rec)
203  record = new Type (*rec);
204  else
205  record = NULL;
206  }
207  void take (Type *rec)
208  {
209  delete record;
210  record = rec;
211  }
212  Type* steal ()
213  {
214  Type *t = record;
215  record = NULL;
216  return t;
217  }
218  Type* c_ptr() const
219  {
220  return record;
221  }
222  RecordHandle& operator= (const RecordHandle &src)
223  {
224  if (record != src.record)
225  {
226  delete record;
227  if (src.record)
228  record = new Type (*src.record);
229  else
230  record = NULL;
231  }
232  return *this;
233  }
234  ~RecordHandle()
235  {
236  delete record;
237  }
238  Type*
239  operator-> ()
240  {
241  return record;
242  }
243  const Type*
244  operator-> () const
245  {
246  return record;
247  }
248  Type&
249  operator* ()
250  {
251  return *record;
252  }
253  const Type&
254  operator* () const
255  {
256  return *record;
257  }
258  Type& operator[] (unsigned int index)
259  {
260  if (index)
261  g_critical ("%s: invalid array subscript: %u", G_STRFUNC, index);
262  return *(index ? NULL : record);
263  }
264  bool is_null() const
265  {
266  return !record;
267  }
268  operator bool () const
269  {
270  return !is_null();
271  }
272  static gpointer
273  boxed_copy (gpointer data)
274  {
275  if (data)
276  {
277  Type *r = reinterpret_cast<Type*> (data);
278  RecordHandle rh (*r);
279  return rh.steal();
280  }
281  return NULL;
282  }
283  static void
284  boxed_free (gpointer data)
285  {
286  if (data)
287  {
288  Type *r = reinterpret_cast<Type*> (data);
289  RecordHandle rh;
290  rh.take (r);
291  }
292  }
293  static RecordHandle
294  value_get_boxed (const GValue *value)
295  {
296  if (SFI_VALUE_HOLDS_REC (value))
297  {
298  SfiRec *rec = sfi_value_get_rec (value);
299  RecordHandle rh = Type::from_rec (rec);
300  return rh;
301  }
302  else
303  {
304  Type *boxed = reinterpret_cast<Type*> (g_value_get_boxed (value));
305  if (boxed)
306  return *boxed;
307  else
308  return INIT_NULL;
309  }
310  }
311  static void
312  value_set_boxed (GValue *value,
313  const RecordHandle &self)
314  {
315  if (SFI_VALUE_HOLDS_REC (value))
316  {
317  SfiRec *rec = Type::to_rec (self);
318  sfi_value_take_rec (value, rec);
319  }
320  else
321  g_value_set_boxed (value, self.c_ptr());
322  }
323 };
324 
325 template<typename Type>
326 class Sequence {
327 public:
328  typedef Type* iterator;
329  typedef const Type* const_iterator;
330  struct CSeq {
331  unsigned int n_elements;
332  Type *elements;
333  };
334  typedef CSeq BoxedType;
335 private:
336  CSeq *cseq;
337 public:
338  Sequence (unsigned int n = 0)
339  {
340  cseq = g_new0 (CSeq, 1);
341  resize (n);
342  }
343  Sequence (const Sequence &sh)
344  {
345  cseq = g_new0 (CSeq, 1);
346  *this = sh;
347  }
348  Sequence (const BoxedType &cs)
349  {
350  cseq = g_new0 (CSeq, 1);
351  set_boxed (&cs);
352  }
353  iterator
354  begin()
355  {
356  return cseq->elements;
357  }
358  const_iterator
359  begin() const
360  {
361  return cseq->elements;
362  }
363  iterator
364  end()
365  {
366  return cseq->elements + cseq->n_elements;
367  }
368  const_iterator
369  end() const
370  {
371  return cseq->elements + cseq->n_elements;
372  }
373  void
374  take (CSeq *cs)
375  {
376  resize (0);
377  if (cs)
378  {
379  g_free (cseq->elements);
380  g_free (cseq);
381  cseq = cs;
382  /* a take(); steal(); sequence needs to preserve pointer */
383  }
384  }
385  CSeq*
386  steal ()
387  {
388  CSeq *cs = cseq;
389  cseq = g_new0 (CSeq, 1);
390  resize (0);
391  /* a take(); steal(); sequence needs to preserve pointer */
392  return cs;
393  }
394  CSeq*
395  c_ptr() const
396  {
397  return cseq;
398  }
399  void
400  resize (unsigned int n)
401  {
402  guint i;
403  // Note that this does *not* use an explicit copy-constructor call to relocate existing elements
404  for (i = n; i < length(); i++)
405  cseq->elements[i].~Type();
406  i = cseq->n_elements;
407  cseq->n_elements = n;
408  cseq->elements = g_renew (Type, cseq->elements, cseq->n_elements);
409  for (; i < length(); i++)
410  new (cseq->elements + i) Type ();
411  }
412  Type&
413  operator[] (unsigned int index)
414  {
415  if (index >= cseq->n_elements)
416  g_critical ("%s: invalid array subscript: %u", G_STRFUNC, index);
417  return cseq->elements[index];
418  }
419  const Type&
420  operator[] (unsigned int index) const
421  {
422  if (index >= cseq->n_elements)
423  g_critical ("%s: invalid array subscript: %u", G_STRFUNC, index);
424  return cseq->elements[index];
425  }
426  Sequence&
427  operator+= (const Type &elm)
428  {
429  // Note that this does *not* use an explicit copy-constructor call to relocate existing elements
430  guint i = cseq->n_elements++;
431  cseq->elements = g_renew (Type, cseq->elements, cseq->n_elements);
432  new (cseq->elements + i) Type (elm);
433  return *this;
434  }
435  void
436  set_boxed (const CSeq *cs)
437  {
438  if (cseq == cs)
439  return;
440  resize (0);
441  if (!cs)
442  return;
443  cseq->n_elements = cs->n_elements;
444  cseq->elements = g_renew (Type, cseq->elements, cseq->n_elements);
445  for (guint i = 0; i < length(); i++)
446  new (cseq->elements + i) Type (cs->elements[i]);
447  }
448  Sequence&
449  operator= (const Sequence &sh)
450  {
451  set_boxed (sh.cseq);
452  return *this;
453  }
454  unsigned int
455  length() const
456  {
457  return cseq ? cseq->n_elements : 0;
458  }
459  ~Sequence()
460  {
461  resize (0);
462  g_free (cseq->elements);
463  g_free (cseq);
464  }
465  static gpointer
466  boxed_copy (gpointer data)
467  {
468  if (data)
469  {
470  CSeq *cs = reinterpret_cast<CSeq*> (data);
471  Sequence s (*cs);
472  return s.steal();
473  }
474  return NULL;
475  }
476  static void
477  boxed_free (gpointer data)
478  {
479  if (data)
480  {
481  CSeq *cs = reinterpret_cast<CSeq*> (data);
482  Sequence s;
483  s.take (cs);
484  }
485  }
486 };
487 template<typename SeqType> SeqType
488 cxx_value_get_boxed_sequence (const GValue *value)
489 {
490  if (SFI_VALUE_HOLDS_SEQ (value))
491  {
492  SfiSeq *seq = sfi_value_get_seq (value);
493  return SeqType::from_seq (seq);
494  }
495  else
496  {
497  typename SeqType::CSeq *boxed = reinterpret_cast<typename SeqType::CSeq*> (g_value_get_boxed (value));
498  if (boxed)
499  {
500  SeqType sh;
501  sh.set_boxed (boxed);
502  return sh;
503  }
504  else
505  return SeqType();
506  }
507 }
508 template<typename SeqType> void
509 cxx_value_set_boxed_sequence (GValue *value,
510  const SeqType &self)
511 {
512  if (SFI_VALUE_HOLDS_SEQ (value))
513  {
514  SfiSeq *seq = SeqType::to_seq (self);
515  sfi_value_take_seq (value, seq);
516  }
517  else
518  g_value_set_boxed (value, self.c_ptr());
519 }
520 
521 class FBlock {
522  SfiFBlock *block;
523 public:
524  typedef float* iterator;
525  typedef const float* const_iterator;
526  FBlock (unsigned int length = 0)
527  {
528  block = sfi_fblock_new_sized (length);
529  }
530  FBlock (SfiFBlock &fblock)
531  {
532  block = NULL;
533  *this = fblock;
534  }
535  FBlock (unsigned int length,
536  const float *values)
537  {
538  block = sfi_fblock_new();
539  sfi_fblock_append (block, length, values);
540  }
541  FBlock (const FBlock &fb)
542  {
543  if (fb.block)
544  block = sfi_fblock_ref (fb.block);
545  else
546  block = sfi_fblock_new();
547  }
548  iterator
549  begin()
550  {
551  return block ? block->values : NULL;
552  }
553  const_iterator
554  begin() const
555  {
556  return block ? block->values : NULL;
557  }
558  iterator
559  end()
560  {
561  return block ? block->values + block->n_values : NULL;
562  }
563  const_iterator
564  end() const
565  {
566  return block ? block->values + block->n_values : NULL;
567  }
568  FBlock&
569  operator= (SfiFBlock &fb)
570  {
571  if (block != &fb)
572  {
573  if (block)
574  sfi_fblock_unref (block);
575  block = &fb;
576  if (block)
577  sfi_fblock_ref (block);
578  }
579  return *this;
580  }
581  FBlock&
582  operator= (const FBlock &s)
583  {
584  if (block != s.block)
585  {
586  if (block)
587  sfi_fblock_unref (block);
588  block = s.block;
589  if (block)
590  sfi_fblock_ref (block);
591  }
592  return *this;
593  }
594  SfiFBlock*
595  fblock()
596  {
597  return block;
598  }
599  ~FBlock()
600  {
601  if (block)
602  sfi_fblock_unref (block);
603  }
604  void
605  ref ()
606  {
607  if (!block)
608  block = sfi_fblock_new();
609  sfi_fblock_ref (block);
610  }
611  void
612  unref ()
613  {
614  RAPICORN_ASSERT_RETURN (block != NULL && block->ref_count > 1);
615  sfi_fblock_unref (block);
616  }
617  void
618  resize (unsigned int length)
619  {
620  if (block)
621  sfi_fblock_resize (block, length);
622  else
623  block = sfi_fblock_new_sized (length);
624  }
625  void
626  take (SfiFBlock *fb)
627  {
628  if (block)
629  sfi_fblock_unref (block);
630  block = fb;
631  }
632  FBlock
633  copy_deep()
634  {
635  if (block)
636  return FBlock (block->n_values, block->values);
637  else
638  return FBlock (0);
639  }
640  FBlock
641  copy_shallow()
642  {
643  return FBlock (*this);
644  }
645  void
646  append (unsigned int length,
647  const float *values)
648  {
649  if (!block)
650  block = sfi_fblock_new();
651  sfi_fblock_append (block, length, values);
652  }
653  void
654  append (float f)
655  {
656  append (1, &f);
657  }
658  unsigned int
659  length()
660  {
661  return block ? block->n_values : 0;
662  }
663  const float*
664  get()
665  {
666  return block ? block->values : NULL;
667  }
668  static FBlock
669  value_get_fblock (const GValue *value)
670  {
671  SfiFBlock *fb = sfi_value_get_fblock (value);
672  FBlock self (0);
673  if (fb)
674  self.take (sfi_fblock_ref (fb));
675  return self;
676  }
677  static void
678  value_set_fblock (GValue *value,
679  const FBlock &self)
680  {
681  sfi_value_set_fblock (value, self.block);
682  }
683 };
684 
685 class BBlock {
686  SfiBBlock *block;
687 public:
688  BBlock (unsigned int length = 0)
689  {
690  block = sfi_bblock_new_sized (length);
691  }
692  BBlock (SfiBBlock &bblock)
693  {
694  block = NULL;
695  *this = bblock;
696  }
697  BBlock (unsigned int length,
698  const guint8 *bytes)
699  {
700  block = sfi_bblock_new();
701  sfi_bblock_append (block, length, bytes);
702  }
703  BBlock (const BBlock &bb)
704  {
705  if (bb.block)
706  block = sfi_bblock_ref (bb.block);
707  else
708  block = sfi_bblock_new();
709  }
710  BBlock&
711  operator= (SfiBBlock &bb)
712  {
713  if (block != &bb)
714  {
715  if (block)
716  sfi_bblock_unref (block);
717  block = &bb;
718  if (block)
719  sfi_bblock_ref (block);
720  }
721  return *this;
722  }
723  BBlock&
724  operator= (const BBlock &s)
725  {
726  if (block != s.block)
727  {
728  if (block)
729  sfi_bblock_unref (block);
730  block = s.block;
731  if (block)
732  sfi_bblock_ref (block);
733  }
734  return *this;
735  }
736  SfiBBlock* bblock()
737  {
738  return block;
739  }
740  ~BBlock()
741  {
742  if (block)
743  sfi_bblock_unref (block);
744  }
745  void
746  ref ()
747  {
748  if (!block)
749  block = sfi_bblock_new();
750  sfi_bblock_ref (block);
751  }
752  void
753  unref ()
754  {
755  RAPICORN_ASSERT_RETURN (block != NULL && block->ref_count > 1);
756  sfi_bblock_unref (block);
757  }
758  void resize (unsigned int length)
759  {
760  if (block)
761  sfi_bblock_resize (block, length);
762  else
763  block = sfi_bblock_new_sized (length);
764  }
765  void
766  take (SfiBBlock *bb)
767  {
768  if (block)
769  sfi_bblock_unref (block);
770  block = bb;
771  }
772  BBlock copy_deep()
773  {
774  if (block)
775  return BBlock (block->n_bytes, block->bytes);
776  else
777  return BBlock (0);
778  }
779  BBlock copy_shallow()
780  {
781  return BBlock (*this);
782  }
783  void append (unsigned int length,
784  const guint8 *bytes)
785  {
786  if (!block)
787  block = sfi_bblock_new();
788  sfi_bblock_append (block, length, bytes);
789  }
790  void append (guint8 b)
791  {
792  append (1, &b);
793  }
794  unsigned int length()
795  {
796  return block ? block->n_bytes : 0;
797  }
798  const guint8* get()
799  {
800  return block ? block->bytes : NULL;
801  }
802  static BBlock value_get_bblock (const GValue *value)
803  {
804  SfiBBlock *bb = sfi_value_get_bblock (value);
805  BBlock self (0);
806  if (bb)
807  self.take (sfi_bblock_ref (bb));
808  return self;
809  }
810  static void value_set_bblock (GValue *value,
811  const BBlock &self)
812  {
813  sfi_value_set_bblock (value, self.block);
814  }
815 };
816 
817 class Rec {
818  SfiRec *crec;
819 public:
820  Rec ()
821  {
822  crec = NULL;
823  }
824  Rec (SfiRec &sr)
825  {
826  crec = NULL;
827  *this = sr;
828  }
829  Rec (const Rec &rr)
830  {
831  if (rr.crec)
832  crec = sfi_rec_ref (rr.crec);
833  else
834  crec = NULL;
835  }
836  void clear ()
837  {
838  if (crec)
839  sfi_rec_clear (crec);
840  }
841  Rec&
842  operator= (SfiRec &sr)
843  {
844  if (crec != &sr)
845  {
846  if (crec)
847  sfi_rec_unref (crec);
848  crec = &sr;
849  if (crec)
850  sfi_rec_ref (crec);
851  }
852  return *this;
853  }
854  Rec&
855  operator= (const Rec &rr)
856  {
857  if (crec != rr.crec)
858  {
859  if (crec)
860  sfi_rec_unref (crec);
861  crec = rr.crec;
862  if (crec)
863  sfi_rec_ref (crec);
864  }
865  return *this;
866  }
867  SfiRec* rec()
868  {
869  return crec;
870  }
871  ~Rec()
872  {
873  if (crec)
874  sfi_rec_unref (crec);
875  }
876  void
877  ref ()
878  {
879  if (!crec)
880  crec = sfi_rec_new();
881  sfi_rec_ref (crec);
882  }
883  void
884  unref ()
885  {
886  RAPICORN_ASSERT_RETURN (crec != NULL && crec->ref_count > 1);
887  sfi_rec_unref (crec);
888  }
889  void
890  take (SfiRec *sr)
891  {
892  if (crec)
893  sfi_rec_unref (crec);
894  crec = sr;
895  }
896  Rec copy_deep()
897  {
898  if (crec)
899  return Rec (*sfi_rec_copy_deep (crec));
900  else
901  return Rec ();
902  }
903  Rec copy_shallow()
904  {
905  return Rec (*this);
906  }
907  void set (const gchar *field_name,
908  const GValue *value)
909  {
910  if (!crec)
911  crec = sfi_rec_new();
912  sfi_rec_set (crec, field_name, value);
913  }
914  unsigned int length()
915  {
916  return crec ? crec->n_fields : 0;
917  }
918  GValue* get (const gchar *name)
919  {
920  return crec ? sfi_rec_get (crec, name) : NULL;
921  }
922  static Rec value_get_rec (const GValue *value)
923  {
924  SfiRec *sr = sfi_value_get_rec (value);
925  Rec self;
926  if (sr)
927  self.take (sfi_rec_ref (sr));
928  return self;
929  }
930  static void value_set_rec (GValue *value,
931  const Rec &self)
932  {
933  sfi_value_set_rec (value, self.crec);
934  }
935 };
936 
938  GObject *cobj;
939 public:
940  ObjectHandle ()
941  {
942  cobj = NULL;
943  }
944  ObjectHandle (GObject &object)
945  {
946  cobj = NULL;
947  *this = object;
948  }
949  ObjectHandle (const ObjectHandle &oh)
950  {
951  if (oh.cobj)
952  cobj = (GObject*) g_object_ref (oh.cobj);
953  else
954  cobj = NULL;
955  }
956  ~ObjectHandle()
957  {
958  if (cobj)
959  g_object_unref (cobj);
960  }
961  ObjectHandle& operator= (GObject &object)
962  {
963  if (cobj != &object)
964  {
965  if (cobj)
966  g_object_unref (cobj);
967  cobj = &object;
968  if (cobj)
969  g_object_ref (cobj);
970  }
971  return *this;
972  }
973  ObjectHandle& operator= (const ObjectHandle &oh)
974  {
975  if (cobj != oh.cobj)
976  {
977  if (cobj)
978  g_object_unref (cobj);
979  cobj = oh.cobj;
980  if (cobj)
981  g_object_ref (cobj);
982  }
983  return *this;
984  }
985  GObject* object()
986  {
987  return cobj;
988  }
989  void
990  ref ()
991  {
992  RAPICORN_ASSERT_RETURN (cobj != NULL && cobj->ref_count > 0);
993  g_object_ref (cobj);
994  }
995  void
996  unref ()
997  {
998  RAPICORN_ASSERT_RETURN (cobj != NULL && cobj->ref_count > 1);
999  g_object_unref (cobj);
1000  }
1001  void
1002  take (GObject *object)
1003  {
1004  if (cobj)
1005  g_object_unref (cobj);
1006  cobj = object;
1007  }
1008  ObjectHandle copy_deep()
1009  {
1010  if (cobj)
1011  return ObjectHandle (*cobj);
1012  else
1013  return ObjectHandle ();
1014  }
1015  ObjectHandle copy_shallow()
1016  {
1017  return ObjectHandle (*this);
1018  }
1019  static ObjectHandle value_get (const GValue *value)
1020  {
1021  GObject *object = (GObject*) g_value_get_object (value);
1022  ObjectHandle self;
1023  if (object)
1024  self.take ((GObject*) g_object_ref (object));
1025  return self;
1026  }
1027  static void value_set (GValue *value,
1028  const ObjectHandle &self)
1029  {
1030  g_value_set_object (value, self.cobj);
1031  }
1032 };
1033 
1034 template<typename Type> void
1035 cxx_boxed_to_rec (const GValue *src_value,
1036  GValue *dest_value)
1037 {
1038  SfiRec *rec = NULL;
1039  gpointer boxed = g_value_get_boxed (src_value);
1040  if (boxed)
1041  {
1042  Type *t = reinterpret_cast<Type*> (boxed);
1043  rec = Type::to_rec (*t);
1044  }
1045  sfi_value_take_rec (dest_value, rec);
1046 }
1047 
1048 template<typename Type> void
1049 cxx_boxed_from_rec (const GValue *src_value,
1050  GValue *dest_value)
1051 {
1052  gpointer boxed = NULL;
1053  SfiRec *rec = sfi_value_get_rec (src_value);
1054  if (rec)
1055  {
1056  RecordHandle<Type> rh = Type::from_rec (rec);
1057  Type *t = rh.steal();
1058  boxed = t;
1059  }
1060  g_value_take_boxed (dest_value, boxed);
1061 }
1062 
1063 template<typename SeqType> void
1064 cxx_boxed_to_seq (const GValue *src_value,
1065  GValue *dest_value)
1066 {
1067  SfiSeq *seq = NULL;
1068  gpointer boxed = g_value_get_boxed (src_value);
1069  if (boxed)
1070  {
1071  typename SeqType::CSeq *t = reinterpret_cast<typename SeqType::CSeq*> (boxed);
1072  SeqType cxxseq;
1073  cxxseq.take(t); /* temporarily re-own */
1074  seq = SeqType::to_seq (cxxseq);
1075  cxxseq.steal(); /* get back */
1076  }
1077  sfi_value_take_seq (dest_value, seq);
1078 }
1079 
1080 template<typename SeqType> void
1081 cxx_boxed_from_seq (const GValue *src_value,
1082  GValue *dest_value)
1083 {
1084  gpointer boxed = NULL;
1085  SfiSeq *seq = sfi_value_get_seq (src_value);
1086  if (seq)
1087  {
1088  SeqType sh = SeqType::from_seq (seq);
1089  typename SeqType::CSeq *t = sh.steal();
1090  boxed = t;
1091  }
1092  g_value_take_boxed (dest_value, boxed);
1093 }
1094 
1095 template<typename Type> RecordHandle<Type>
1096 cxx_value_get_rec (const GValue *value)
1097 {
1098  SfiRec *rec = sfi_value_get_rec (value);
1099  if (rec)
1100  return Type::from_rec (rec);
1101  else
1102  return INIT_NULL;
1103 }
1104 
1105 template<typename Type> void
1106 cxx_value_set_rec (GValue *value,
1107  const RecordHandle<Type> &self)
1108 {
1109  if (self)
1110  sfi_value_take_rec (value, Type::to_rec (self));
1111  else
1112  sfi_value_set_rec (value, NULL);
1113 }
1114 
1115 template<typename SeqType> SeqType
1116 cxx_value_get_seq (const GValue *value)
1117 {
1118  SfiSeq *seq = sfi_value_get_seq (value);
1119  if (seq)
1120  return SeqType::from_seq (seq);
1121  else
1122  return SeqType();
1123 }
1124 
1125 template<typename SeqType> void
1126 cxx_value_set_seq (GValue *value,
1127  const SeqType &self)
1128 {
1129  sfi_value_take_seq (value, SeqType::to_seq (self));
1130 }
1131 
1132 // == C++ Auxillaries ==
1133 struct Init { // stolen from Rapicorn
1134  explicit Init (void (*f) ()) { f(); }
1135 };
1136 
1137 } // Sfi
1138 
1139 #endif /* __SFI_CXX_H__ */
1140 
1141 /* vim:set ts=8 sts=2 sw=2: */
void resize(uint w, uint h)
Definition: sficxx.hh:817
Definition: sficxx.hh:685
STL class.
Definition: sficxx.hh:330
strlen
Definition: sficxx.hh:326
strcmp
Definition: sficxx.hh:521
#define RAPICORN_ASSERT_RETURN(cond,...)
T c_str(T...args)
Definition: sficxx.hh:169
Definition: sficxx.hh:143
Definition: sficxx.hh:16
The Sfi namespace contains utilities for synthesis.
Definition: sfi.hh:9