From: Dan Eble Date: Tue, 25 Aug 2015 15:54:21 +0000 (-0400) Subject: Issue 4577: Remove the nasty workaround for platforms that don't provide X-Git-Tag: release/2.19.27-1~4 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=d36ec1303bce389c9251765e8f2ae25717c74183;p=lilypond.git Issue 4577: Remove the nasty workaround for platforms that don't provide std::vector::data(). Replace most code that reached into into Grob_array and modified its internal vector with calls to new member functions such as filter(). Move the definitions of some trivial methods into grob-array.hh. --- diff --git a/flower/include/std-vector.hh b/flower/include/std-vector.hh index fae955854b..589f7c0db2 100644 --- a/flower/include/std-vector.hh +++ b/flower/include/std-vector.hh @@ -68,56 +68,7 @@ typedef size_t vsize; #define VPOS ((vsize) -1) #endif -#if HAVE_STL_DATA_METHOD #include -#else /* !HAVE_STL_DATA_METHOD */ -#define vector __flower_vector -#include -#undef vector - -namespace std -{ - -/* Interface without pointer arithmetic (iterator) semantics. */ -template > -class vector : public __flower_vector -{ -public: - typedef typename __flower_vector::iterator iterator; - typedef typename __flower_vector::const_iterator const_iterator; - - vector () : __flower_vector () - { - } - - vector (size_t n) : __flower_vector (n) - { - } - - vector (vector const &v) : __flower_vector (v) - { - } - - vector (const_iterator b, const_iterator e) : __flower_vector (b, e) - { - } - - T * - data () - { - return &(*this)[0]; - } - - T const * - data () const - { - return &(*this)[0]; - } -}; - -} /* namespace std */ - -#endif /* !HAVE_STL_DATA_METHOD */ template T const & diff --git a/lily/break-substitution.cc b/lily/break-substitution.cc index c465979fb7..d198753d67 100644 --- a/lily/break-substitution.cc +++ b/lily/break-substitution.cc @@ -147,34 +147,6 @@ again: return src; } -/* - Perform substitution on GROB_LIST using a constant amount of stack. -*/ -vector temporary_substition_array; -void -substitute_grob_array (Grob_array *grob_arr, Grob_array *new_arr) -{ - vector &old_grobs (grob_arr->array_reference ()); - vector *new_grobs (new_arr == grob_arr - ? & temporary_substition_array - : &new_arr->array_reference ()); - - new_grobs->resize (old_grobs.size ()); - Grob **array = (Grob **) new_grobs->data (); - Grob **ptr = array; - for (vsize i = 0; i < old_grobs.size (); i++) - { - Grob *orig = old_grobs[i]; - Grob *new_grob = substitute_grob (orig); - if (new_grob) - *ptr++ = new_grob; - } - - new_grobs->resize (ptr - array); - if (new_arr == grob_arr) - new_arr->set_array (*new_grobs); -} - /* We don't do @@ -470,8 +442,8 @@ substitute_object_alist (SCM alist, SCM dest) : Grob_array::make_array (); Grob_array *new_arr = unsmob (newval); - - substitute_grob_array (orig, new_arr); + // TODO: What if new_arr is null? + new_arr->filter_map_assign (*orig, substitute_grob); val = newval; } else @@ -516,7 +488,8 @@ Spanner::substitute_one_mutable_property (SCM sym, newval = Grob_array::make_array (); sc->set_object (sym, newval); } - substitute_grob_array (grob_array, unsmob (newval)); + Grob_array *new_arr = unsmob (newval); + new_arr->filter_map_assign (*grob_array, substitute_grob); } else { diff --git a/lily/grob-array.cc b/lily/grob-array.cc index 8fc60387bc..ec0ee43e18 100644 --- a/lily/grob-array.cc +++ b/lily/grob-array.cc @@ -39,18 +39,6 @@ Grob_array::Grob_array () ordered_ = true; } -vector & -Grob_array::array_reference () -{ - return grobs_; -} - -vector const & -Grob_array::array () const -{ - return grobs_; -} - SCM Grob_array::mark_smob () const { @@ -81,12 +69,6 @@ Grob_array::make_array () return ga.smobbed_copy (); } -void -Grob_array::clear () -{ - grobs_.clear (); -} - void Grob_array::remove_duplicates () { @@ -95,16 +77,43 @@ Grob_array::remove_duplicates () uniquify (grobs_); } -bool -Grob_array::empty () const +void +Grob_array::filter (bool (*predicate) (const Grob *)) +{ + vsize new_size = 0; + for (vsize i = 0; i < grobs_.size (); ++i) + if (predicate (grobs_[i])) + grobs_[new_size++] = grobs_[i]; + grobs_.resize (new_size); + // could call grobs_.shrink_to_fit () with C++11 +} + +void +Grob_array::filter_map (Grob * (*map_fun) (Grob *)) { - return grobs_.empty (); + vsize new_size = 0; + for (vsize i = 0; i < grobs_.size (); ++i) + if (Grob *grob = map_fun (grobs_[i])) + grobs_[new_size++] = grob; + grobs_.resize (new_size); + // could call grobs_.shrink_to_fit () with C++11 } void -Grob_array::set_array (vector const &src) +Grob_array::filter_map_assign (const Grob_array &src, + Grob * (*map_fun) (Grob *)) { - grobs_ = src; + if (&src != this) + { + grobs_.resize (0); + grobs_.reserve (src.grobs_.size ()); + for (vsize i = 0; i < src.grobs_.size (); i++) + if (Grob *grob = map_fun (src.grobs_[i])) + grobs_.push_back (grob); + // could call grobs_.shrink_to_fit () with C++11 + } + else + filter_map (map_fun); } const char Grob_array::type_p_name_[] = "ly:grob-array?"; diff --git a/lily/include/grob-array.hh b/lily/include/grob-array.hh index e3963f019d..1a755fe661 100644 --- a/lily/include/grob-array.hh +++ b/lily/include/grob-array.hh @@ -43,14 +43,27 @@ public: Spanner *spanner (vsize i); Grob *grob (vsize i) const { return grobs_.at (i); } vsize size () const { return grobs_.size (); } - bool empty () const; + bool empty () const { return grobs_.empty (); } void remove_duplicates (); - void clear (); + void clear () { grobs_.clear (); } void add (Grob *x) { grobs_.push_back (x); } - void set_array (vector const &src); - vector &array_reference (); - vector const &array () const; + void set_array (vector const &src) { grobs_ = src; } + vector &array_reference () { return grobs_; } + vector const &array () const { return grobs_; } static SCM make_array (); + + // Remove grobs that do not satisfy the predicate, leaving the order + // unchanged. + void filter (bool (*predicate) (const Grob *)); + + // Run a function on all grobs in this array. If the function returns null, + // remove the original grob, reducing the size of the array. If the function + // returns a Grob, replace the original grob with the returned Grob. + void filter_map (Grob * (*map_fun) (Grob *)); + + // Like src.filter_map (f), but store the result in this array instead of + // mutating the input. + void filter_map_assign (const Grob_array &src, Grob * (*map_fun) (Grob *)); }; diff --git a/lily/paper-column.cc b/lily/paper-column.cc index 3ea5a89f05..da3807c31d 100644 --- a/lily/paper-column.cc +++ b/lily/paper-column.cc @@ -390,6 +390,11 @@ Paper_column::print (SCM p) return t.smobbed_copy (); } +static bool grob_is_live (const Grob *g) +{ + return g && g->is_live (); +} + /* This is all too hairy. We use bounded-by-me to make sure that some columns are kept "alive". Unfortunately, when spanners are suicided, @@ -404,21 +409,8 @@ Paper_column::before_line_breaking (SCM grob) { Grob *me = unsmob (grob); - SCM bbm = me->get_object ("bounded-by-me"); - Grob_array *ga = unsmob (bbm); - if (!ga) - return SCM_UNSPECIFIED; - - vector &array (ga->array_reference ()); - - for (vsize i = array.size (); i--;) - { - Grob *g = array[i]; - - if (!g || !g->is_live ()) - /* UGH . potentially quadratic. */ - array.erase (array.begin () + i); - } + if (Grob_array *ga = unsmob (me->get_object ("bounded-by-me"))) + ga->filter (grob_is_live); return SCM_UNSPECIFIED; } diff --git a/lily/pure-from-neighbor-interface.cc b/lily/pure-from-neighbor-interface.cc index d78d8d619c..745c23dbec 100644 --- a/lily/pure-from-neighbor-interface.cc +++ b/lily/pure-from-neighbor-interface.cc @@ -41,13 +41,8 @@ Pure_from_neighbor_interface::calc_pure_relevant_grobs (SCM smob) vector new_elts; new_elts.insert (new_elts.end (), elts.begin (), elts.end ()); - SCM neighbors_scm = me->get_object ("neighbors"); - if (unsmob (neighbors_scm)) - { - vector &arr - = unsmob (neighbors_scm)->array_reference (); - arr = new_elts; - } + if (Grob_array *a = unsmob (me->get_object ("neighbors"))) + a->set_array (new_elts); return Axis_group_interface::internal_calc_pure_relevant_grobs (me, "neighbors"); } diff --git a/lily/slur.cc b/lily/slur.cc index a11a30258e..5f95e5d4d6 100644 --- a/lily/slur.cc +++ b/lily/slur.cc @@ -219,13 +219,8 @@ Slur::replace_breakable_encompass_objects (Grob *me) new_encompasses.push_back (g); } - SCM encompass_scm = me->get_object ("encompass-objects"); - if (unsmob (encompass_scm)) - { - vector &arr - = unsmob (encompass_scm)->array_reference (); - arr = new_encompasses; - } + if (Grob_array *a = unsmob (me->get_object ("encompass-objects"))) + a->set_array (new_encompasses); } Bezier diff --git a/lily/system.cc b/lily/system.cc index 4a18ab52b7..0551b85cbc 100644 --- a/lily/system.cc +++ b/lily/system.cc @@ -106,16 +106,9 @@ System::typeset_grob (Grob *elem) void System::derived_mark () const { - if (!all_elements_->empty ()) - { - Grob **ptr = &all_elements_->array_reference ()[0]; - Grob **end = ptr + all_elements_->size (); - while (ptr < end) - { - scm_gc_mark ((*ptr)->self_scm ()); - ptr++; - } - } + const vector &arr = all_elements_->array (); + for (vsize i = arr.size (); i--;) + scm_gc_mark (arr[i]->self_scm ()); if (pscore_) scm_gc_mark (pscore_->self_scm ());