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