]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/small-smobs.hh
Merge remote branch 'origin/master' into release/unstable
[lilypond.git] / lily / include / small-smobs.hh
1 #ifndef SMALL_SMOBS_HH
2 #define SMALL_SMOBS_HH
3
4 #include "smobs.hh"
5
6 #if GUILEV2
7 // Fix the APIs of GUILE2.x, broken in 2009--2014
8 #undef SCM_SMOB_OBJECT_LOC
9 #undef SCM_SMOB_OBJECT_2_LOC
10 #undef SCM_SMOB_OBJECT_3_LOC
11 #define SCM_SMOB_OBJECT_LOC(x)          (SCM_SMOB_OBJECT_N_LOC ((x), 1))
12 #define SCM_SMOB_OBJECT_2_LOC(x)        (SCM_SMOB_OBJECT_N_LOC ((x), 2))
13 #define SCM_SMOB_OBJECT_3_LOC(x)        (SCM_SMOB_OBJECT_N_LOC ((x), 3))
14 #endif
15
16 // This is tricky: the small smobs contain all the data in the smob
17 // itself.  Any derived classes must _not_ contain any data members or
18 // be polymorphic (contain a virtual table pointer) as there is no
19 // place to store any of that.  The class itself does not contain a
20 // data member either.  Pointers to it are basically meaningless and
21 // are instead reinterpreted directly as an SCM value in order to have
22 // unsmob and friends behave as customary.
23
24 template <class Super>
25 class Smob1 : public Smob_base<Super>
26 {
27   Smob1 (); // Do not define!  Not constructible!
28   Smob1 (const Smob1 &); // Do not define!  Not copyable!
29 public:
30   SCM self_scm () const { return SCM_PACK (this); }
31   SCM & scm1 () const { return *SCM_SMOB_OBJECT_LOC (self_scm ()); }
32   static SCM make_smob (SCM arg1 = SCM_UNDEFINED) {
33     SCM_RETURN_NEWSMOB (Smob_base<Super>::smob_tag (), SCM_UNPACK (arg1));
34   }
35   SCM mark_smob () { return scm1 (); };
36   static Super *unchecked_unsmob (SCM s) {
37     return reinterpret_cast<Super *> (SCM_UNPACK (s));
38   }
39 };
40
41 template <class Super>
42 class Smob2 : public Smob_base<Super>
43 {
44   Smob2 (); // Do not define!  Not constructible!
45   Smob2 (const Smob2 &); // Do not define!  Not copyable!
46 public:
47   SCM self_scm () const { return SCM_PACK (this); }
48   SCM & scm1 () const { return *SCM_SMOB_OBJECT_LOC (self_scm ()); }
49   SCM & scm2 () const { return *SCM_SMOB_OBJECT_2_LOC (self_scm ()); }
50   static SCM make_smob (SCM arg1 = SCM_UNDEFINED, SCM arg2 = SCM_UNDEFINED) {
51     SCM_RETURN_NEWSMOB2 (Smob_base<Super>::smob_tag (),
52                          SCM_UNPACK (arg1),
53                          SCM_UNPACK (arg2));
54   }
55   SCM mark_smob ()
56   {
57     scm_gc_mark (scm2 ());
58     return scm1 ();
59   }
60   static Super *unchecked_unsmob (SCM s) {
61     return reinterpret_cast<Super *> (SCM_UNPACK (s));
62   }
63 };
64
65 template <class Super>
66 class Smob3 : public Smob_base<Super>
67 {
68   Smob3 (); // Do not define!  Not constructible!
69   Smob3 (const Smob3 &); // Do not define!  Not copyable!
70 public:
71   SCM self_scm () const { return SCM_PACK (this); }
72   SCM & scm1 () const { return *SCM_SMOB_OBJECT_LOC (self_scm ()); }
73   SCM & scm2 () const { return *SCM_SMOB_OBJECT_2_LOC (self_scm ()); }
74   SCM & scm3 () const { return *SCM_SMOB_OBJECT_3_LOC (self_scm ()); }
75   static SCM make_smob (SCM arg1 = SCM_UNDEFINED,
76                         SCM arg2 = SCM_UNDEFINED,
77                         SCM arg3 = SCM_UNDEFINED) {
78     SCM_RETURN_NEWSMOB3 (Smob_base<Super>::smob_tag (),
79                          SCM_UNPACK (arg1),
80                          SCM_UNPACK (arg2),
81                          SCM_UNPACK (arg3));
82   }
83   SCM mark_smob ()
84   {
85     scm_gc_mark (scm3 ());
86     scm_gc_mark (scm2 ());
87     return scm1 ();
88   }
89   static Super *unchecked_unsmob (SCM s) {
90     return reinterpret_cast<Super *> (SCM_UNPACK (s));
91   }
92 };
93
94 #endif