]> git.donarmstrong.com Git - lilypond.git/blob - lily/grob-array.cc
Web-ja: update introduction
[lilypond.git] / lily / grob-array.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2005--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 #include "grob-array.hh"
21 #include "item.hh"
22 #include "spanner.hh"
23
24
25 Item *
26 Grob_array::item (vsize i)
27 {
28   return dynamic_cast<Item *> (grobs_.at (i));
29 }
30
31 Spanner *
32 Grob_array::spanner (vsize i)
33 {
34   return dynamic_cast<Spanner *> (grobs_.at (i));
35 }
36
37 Grob_array::Grob_array ()
38 {
39   ordered_ = true;
40 }
41
42 SCM
43 Grob_array::mark_smob () const
44 {
45 #if 0  /* see System::derived_mark () const */
46   for (vsize i = 0; i < grobs_.size (); i++)
47     scm_gc_mark (grobs_[i]->self_scm ());
48 #endif
49   return SCM_UNDEFINED;
50 }
51
52 int
53 Grob_array::print_smob (SCM port, scm_print_state *) const
54 {
55   scm_puts ("#<Grob_array", port);
56   for (vsize i = 0; i < size (); i++)
57     {
58       scm_display (grob (i)->self_scm (), port);
59       scm_puts (" ", port);
60     }
61   scm_puts (">", port);
62   return 1;
63 }
64
65 SCM
66 Grob_array::make_array ()
67 {
68   Grob_array ga;
69   return ga.smobbed_copy ();
70 }
71
72 void
73 Grob_array::remove_duplicates ()
74 {
75   assert (!ordered_);
76
77   uniquify (grobs_);
78 }
79
80 void
81 Grob_array::filter (bool (*predicate) (const Grob *))
82 {
83   vsize new_size = 0;
84   for (vsize i = 0; i < grobs_.size (); ++i)
85     if (predicate (grobs_[i]))
86       grobs_[new_size++] = grobs_[i];
87   grobs_.resize (new_size);
88   // could call grobs_.shrink_to_fit () with C++11
89 }
90
91 void
92 Grob_array::filter_map (Grob * (*map_fun) (Grob *))
93 {
94   vsize new_size = 0;
95   for (vsize i = 0; i < grobs_.size (); ++i)
96     if (Grob *grob = map_fun (grobs_[i]))
97       grobs_[new_size++] = grob;
98   grobs_.resize (new_size);
99   // could call grobs_.shrink_to_fit () with C++11
100 }
101
102 void
103 Grob_array::filter_map_assign (const Grob_array &src,
104                                Grob * (*map_fun) (Grob *))
105 {
106   if (&src != this)
107     {
108       grobs_.resize (0);
109       grobs_.reserve (src.grobs_.size ());
110       for (vsize i = 0; i < src.grobs_.size (); i++)
111         if (Grob *grob = map_fun (src.grobs_[i]))
112           grobs_.push_back (grob);
113       // could call grobs_.shrink_to_fit () with C++11
114     }
115   else
116     filter_map (map_fun);
117 }
118
119 const char * const Grob_array::type_p_name_ = "ly:grob-array?";
120
121
122 SCM
123 grob_list_to_grob_array (SCM lst)
124 {
125   SCM arr_scm = Grob_array::make_array ();
126   Grob_array *ga = unsmob<Grob_array> (arr_scm);
127   for (SCM s = lst; scm_is_pair (s); s = scm_cdr (s))
128     ga->add (unsmob<Grob> (scm_car (s)));
129   return arr_scm;
130 }
131
132 SCM
133 grob_array_to_list (Grob_array *array)
134 {
135   SCM list = SCM_EOL;
136   SCM *tail = &list;
137
138   for (vsize i = 0; i < array->size (); i++)
139     {
140       *tail = scm_cons (array->grob (i)->self_scm (), SCM_EOL);
141       tail = SCM_CDRLOC (*tail);
142     }
143   return list;
144 }