]> git.donarmstrong.com Git - lilypond.git/blob - lily/include/smobs.hh
Issue 4550 (2/2) Avoid "using namespace std;" in included files
[lilypond.git] / lily / include / smobs.hh
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 1999--2015 Han-Wen Nienhuys <hanwen@xs4all.nl>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef SMOBS_HH
21 #define SMOBS_HH
22
23 #include "lily-guile.hh"
24 #include "lily-proto.hh"
25 #include "warn.hh"
26 #include <string>
27
28 /*
29   Smobs are GUILEs mechanism of exporting C(++) objects to the Scheme
30   world.  They are documented in the GUILE manual.
31
32
33   In LilyPond, C++ objects can be placed under the control of GUILE's
34   type system and garbage collection mechanism by inheriting from one
35   of several Smob base classes.
36
37   There are two types of smob objects.
38
39   1. Simple smobs are intended for simple objects like numbers:
40   immutable objects that can be copied without change of meaning.
41
42   To obtain an SCM version of a simple smob, use the member function
43   SCM smobbed_copy ().
44
45   Simple smobs are created by deriving from Simple_smob<Classname>.
46
47   A simple smob is only optionally under the reign of the GUILE
48   garbage collector: its usual life time is that of a normal C++
49   object.  While a smobbed_copy () is fully under control of the
50   garbage collector and will have its mark_smob function called during
51   garbage collection, an automatic variable of this type will not have
52   mark_smob called, but rather have its memory image in the call stack
53   scanned for contained non-immediate SCM values.  Anything requiring
54   more complex mark_smob behavior is not suitable for a simple smob.
55
56   When you create a smobbed_copy, the _copy_ is fully managed by the
57   GUILE memory system.  As a corollary, multiple smobbed_copy calls
58   yield multiple GUILE objects generally not eq? to each other.
59
60   2. Complex smobs are objects that have an identity. These objects
61   carry this identity in the form of a self_scm () method, which is a
62   SCM pointer to the object itself.  Complex smobs are always under
63   control of the GUILE memory system.
64
65   The constructor for a complex smob should have 3 steps:
66
67   * initialize all SCM members to an immediate value (like SCM_EOL)
68
69   * call smobify_self ()
70
71   * initialize SCM members
72
73   For example,
74
75   Complex_smob::Complex_smob : public Smob<Complex_smob> () {
76   scm_member_ = SCM_EOL;
77   smobify_self ();
78   scm_member_ = <..what you want to store..>
79   }
80
81   after construction, the self_scm () field of a complex smob is
82   protected from Garbage Collection.  This protection should be
83   removed once the object is put into another (reachable) Scheme data
84   structure, i.e.
85
86   Complex_smob *p = new Complex_smob;
87   list = scm_cons (p->self_scm (), list);
88   p->unprotect ();
89
90   Since unprotect returns the SCM object itself, this particular case
91   can be written as
92
93   Complex_smob *p = new Complex_smob;
94   list = scm_cons (p->unprotect (), list);
95
96   Complex smobs are created by deriving from Smob<Classname>.
97
98   CALLING INTERFACE
99
100   Common global functions for accessing C++ smob objects:
101
102   - unsmob<T> (SCM x) - unpack X and return a pointer to the C++ object,
103     or 0 if it has the wrong type.
104
105   IMPLEMENTATION
106
107   For implementating a class, the following public members can be
108   provided in the top class itself:
109
110   - SCM equal_p (SCM a, SCM b) - compare A and B. Returns a Scheme
111     boolean.  If the class does not define this function, equal? will
112     be equivalent to eq?.  The function will only be called when both
113     objects are of the respective type and not eq? to each other.
114
115   - mark_smob () function, that calls scm_gc_mark () on all Scheme
116     objects in the class.  If the class does not define this function,
117     it must not contain non-immediate Scheme values.
118
119   - a print_smob () function, that displays a representation for
120     debugging purposes.  If the class does not define this function,
121     the output will be #<Classname> when printing.
122
123   - a static const type_p_name_[] std::string set to something like
124     "ly:grob?".  When provided, an accordingly named function for
125     checking for the given smob type will be available in Scheme.
126
127 */
128
129 // Initialization class.  Create a variable or static data member of
130 // this type at global scope (or creation will happen too late for
131 // Scheme initialization), initialising with a function to be called.
132 // Reference somewhere (like in the constructor of the containing
133 // class) to make sure the variable is actually instantiated.
134
135 class Scm_init {
136   static const Scm_init * list_;
137   void (*const fun_)(void);
138   Scm_init const * const next_;
139   Scm_init ();          // don't use default constructor, don't define
140   Scm_init (const Scm_init &);  // don't define copy constructor
141 public:
142   Scm_init (void (*fun) (void)) : fun_ (fun), next_ (list_)
143   { list_ = this; }
144   static void init ();
145 };
146
147 template <class Super>
148 class Smob_base
149 {
150   static scm_t_bits smob_tag_;
151   static Scm_init scm_init_;
152   static void init (void);
153   static std::string smob_name_;
154 protected:
155   static Super *unchecked_unsmob (SCM s)
156   {
157     return reinterpret_cast<Super *> (SCM_SMOB_DATA (s));
158   }
159   // reference scm_init_ in smob_tag which is sure to be called.  The
160   // constructor, in contrast, may not be called at all in classes
161   // like Smob1.
162   static scm_t_bits smob_tag () { (void) scm_init_; return smob_tag_; }
163   Smob_base () { }
164   static SCM register_ptr (Super *p);
165   static Super *unregister_ptr (SCM obj);
166 private:
167   // Those fallbacks are _only_ for internal use by Smob_base.  They
168   // are characterized by no knowledge about the implemented type
169   // apart from the type's name.  Overriding them as a template
170   // specialization is _not_ intended since a type-dependent
171   // implementation will in general need access to possibly private
172   // parts of the Super class.  So any class-dependent override should
173   // be done by redefining the respective function in the Super class
174   // (where it will mask the private template member) rather than
175   // specializing a different template function/pointer.
176   //
177   // Most default functions are do-nothings.  void init() will
178   // recognize their address when not overriden and will then refrain
179   // altogether from passing the the respective callbacks to GUILE.
180   SCM mark_smob (void) const;
181   static SCM mark_trampoline (SCM); // Used for calling mark_smob
182   static size_t free_smob (SCM obj);
183   static SCM equal_p (SCM, SCM);
184   int print_smob (SCM, scm_print_state *) const;
185   static int print_trampoline (SCM, SCM, scm_print_state *);
186   static void smob_proc_init (scm_t_bits) { };
187
188   // type_p_name_ can be overriden in the Super class with a static
189   // const char [] std::string.  This requires both a declaration in the
190   // class as well as a single instantiation outside.  Using a
191   // template specialization for supplying a different std::string name
192   // right in Smob_base<Super> itself seems tempting, but the C++
193   // rules would then require a specialization declaration at the
194   // class definition site as well as a specialization instantiation
195   // in a single compilation unit.  That requires just as much source
196   // code maintenance while being harder to understand and quite
197   // trickier in its failure symptoms when things go wrong.  So we
198   // just use a static zero as "not here" indication.
199   static const int type_p_name_ = 0;
200
201   // LY_DECLARE_SMOB_PROC is used in the Super class definition for
202   // making a smob callable like a function.  Its first argument is a
203   // function member pointer constant, to a function taking the
204   // correct number of SCM arguments and returning SCM.  The function
205   // itself has to be defined separately.
206
207 #define LY_DECLARE_SMOB_PROC(PMF, REQ, OPT, VAR)                        \
208   static void smob_proc_init (scm_t_bits smob_tag)                      \
209   {                                                                     \
210     scm_set_smob_apply (smob_tag,                                       \
211                         (scm_t_subr)smob_trampoline<PMF>,               \
212                         REQ, OPT, VAR);                                 \
213   }
214
215   // Well, function template argument packs are a C++11 feature.  So
216   // we just define a bunch of trampolines manually.  It turns out
217   // that GUILEĀ 1.8.8 cannot actually make callable structures with
218   // more than 3 arguments anyway.  That's surprising, to say the
219   // least, but in emergency situations one can always use a "rest"
220   // argument and take it apart manually.
221
222   template <SCM (Super::*pmf)(void)>
223   static SCM smob_trampoline (SCM self)
224   {
225     return (Super::unchecked_unsmob (self)->*pmf)();
226   }
227   template <SCM (Super::*pmf)(SCM)>
228   static SCM smob_trampoline (SCM self, SCM arg1)
229   {
230     return (Super::unchecked_unsmob (self)->*pmf)(arg1);
231   }
232   template <SCM (Super::*pmf)(SCM, SCM)>
233   static SCM smob_trampoline (SCM self, SCM arg1, SCM arg2)
234   {
235     return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2);
236   }
237   template <SCM (Super::*pmf)(SCM, SCM, SCM)>
238   static SCM smob_trampoline (SCM self, SCM arg1, SCM arg2, SCM arg3)
239   {
240     return (Super::unchecked_unsmob (self)->*pmf)(arg1, arg2, arg3);
241   }
242
243   static bool is_smob (SCM s)
244   {
245     return SCM_SMOB_PREDICATE (smob_tag (), s);
246   }
247   static SCM smob_p (SCM s)
248   {
249     return is_smob (s) ? SCM_BOOL_T : SCM_BOOL_F;
250   }
251
252   template <class T>
253   friend T *unsmob (SCM s);
254
255   template <class T>
256   friend T *ly_assert_smob (SCM s, int number, const char *fun);
257 };
258
259 template <class T>
260 inline T *unsmob (SCM s)
261 {
262   return T::is_smob (s) ? dynamic_cast<T *> (T::unchecked_unsmob (s)) : 0;
263 }
264
265 // Simple smobs
266 template <class Super>
267 class Simple_smob : public Smob_base<Super> {
268 public:
269   static size_t free_smob (SCM obj)
270   {
271     delete Smob_base<Super>::unregister_ptr (obj);
272     return 0;
273   }
274   SCM smobbed_copy () const
275   {
276     Super *p = new Super(*static_cast<const Super *> (this));
277     return Smob_base<Super>::register_ptr (p);
278   }
279 };
280
281 void protect_smob (SCM smob, SCM *prot_cons);
282 void unprotect_smob (SCM smob, SCM *prot_cons);
283
284 // The Smob_core class is not templated and contains material not
285 // depending on the Super class.
286
287 class Smob_core {
288 protected:
289   SCM self_scm_;
290   Smob_core () : self_scm_ (SCM_UNDEFINED) { };
291 public:
292   SCM self_scm () const { return self_scm_; }
293   Listener get_listener (SCM callback);
294 };
295
296 template <class Super>
297 class Smob : public Smob_core, public Smob_base<Super> {
298 private:
299   SCM protection_cons_;
300   Smob (const Smob<Super> &); // Do not define!  Not copyable!
301 protected:
302   Smob () : protection_cons_ (SCM_EOL) { };
303 public:
304   static size_t free_smob (SCM obj)
305   {
306     delete Smob_base<Super>::unregister_ptr (obj);
307     return 0;
308   }
309   SCM unprotected_smobify_self ()
310   {
311     SCM s = Smob_base<Super>::register_ptr (static_cast<Super *> (this));
312     self_scm_ = s;
313     return s;
314   }
315   void protect ()
316   {
317     protect_smob (self_scm_, &protection_cons_);
318   }
319   void smobify_self () {
320     protect_smob (unprotected_smobify_self (), &protection_cons_);
321   }
322   SCM unprotect ()
323   {
324     SCM s = self_scm_;
325     unprotect_smob (s, &protection_cons_);
326     return s;
327   }
328 };
329
330 extern bool parsed_objects_should_be_dead;
331 class parsed_dead
332 {
333   static std::vector<parsed_dead *> elements;
334   SCM data;
335   SCM readout_one ()
336   {
337     SCM res = data;
338     data = SCM_UNDEFINED;
339     return res;
340   }
341 public:
342   parsed_dead () : data (SCM_UNDEFINED)
343   {
344     elements.push_back (this);
345   }
346   void checkin (SCM arg) { data = arg; }
347   static SCM readout ();
348 };
349
350 // This does not appear to work with GUILEv2's garbage collector:
351 // Objects are found in the GC phase but printing them will crash at
352 // least some, so they are apparently not protected in spite of being
353 // included in the GC scans.  So it would appear that scanning smobs
354 // is not equivalent to marking them.  Ugh.
355 #if defined(DEBUG) && !GUILEV2
356 #define ASSERT_LIVE_IS_ALLOWED(arg)                                     \
357   do {                                                                  \
358     static parsed_dead pass_here;                                       \
359     if (parsed_objects_should_be_dead)                                  \
360       pass_here.checkin (arg);                                          \
361   } while (0)
362 #else
363 #define ASSERT_LIVE_IS_ALLOWED(arg) do { (void)(arg); }  \
364   while (0)
365 #endif
366
367 #include "smobs.tcc"
368 #endif /* SMOBS_HH */