]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4577: Remove the nasty workaround for platforms that don't provide
authorDan Eble <nine.fierce.ballads@gmail.com>
Tue, 25 Aug 2015 15:54:21 +0000 (11:54 -0400)
committerDan Eble <nine.fierce.ballads@gmail.com>
Fri, 11 Sep 2015 12:15:40 +0000 (08:15 -0400)
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.

flower/include/std-vector.hh
lily/break-substitution.cc
lily/grob-array.cc
lily/include/grob-array.hh
lily/paper-column.cc
lily/pure-from-neighbor-interface.cc
lily/slur.cc
lily/system.cc

index fae955854ba63dea1e362881d4e647fde3d61a29..589f7c0db2063a2110241668c5d2ac7ba39d39ce 100644 (file)
@@ -68,56 +68,7 @@ typedef size_t vsize;
 #define VPOS ((vsize) -1)
 #endif
 
-#if HAVE_STL_DATA_METHOD
 #include <vector>
-#else /* !HAVE_STL_DATA_METHOD */
-#define vector __flower_vector
-#include <vector>
-#undef vector
-
-namespace std
-{
-
-/* Interface without pointer arithmetic (iterator) semantics.  */
-template<typename T, typename A = std::allocator<T> >
-class vector : public __flower_vector<T, A>
-{
-public:
-  typedef typename __flower_vector<T>::iterator iterator;
-  typedef typename __flower_vector<T>::const_iterator const_iterator;
-
-  vector<T, A> () : __flower_vector<T, A> ()
-  {
-  }
-
-  vector<T, A> (size_t n) : __flower_vector<T, A> (n)
-  {
-  }
-
-  vector<T, A> (vector<T, A> const &v) : __flower_vector<T, A> (v)
-  {
-  }
-
-  vector<T, A> (const_iterator b, const_iterator e) : __flower_vector<T, A> (b, e)
-  {
-  }
-
-  T *
-  data ()
-  {
-    return &(*this)[0];
-  }
-
-  T const *
-  data () const
-  {
-    return &(*this)[0];
-  }
-};
-
-} /* namespace std */
-
-#endif /* !HAVE_STL_DATA_METHOD */
 
 template<typename T>
 T const &
index c465979fb7f5f9abb53a809b523842b321f6023e..d198753d673b88bda66d51e8029259f9d4307681 100644 (file)
@@ -147,34 +147,6 @@ again:
   return src;
 }
 
-/*
-  Perform substitution on GROB_LIST using a constant amount of stack.
-*/
-vector<Grob *> temporary_substition_array;
-void
-substitute_grob_array (Grob_array *grob_arr, Grob_array *new_arr)
-{
-  vector<Grob *> &old_grobs (grob_arr->array_reference ());
-  vector<Grob *> *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<Grob_array> (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<Grob_array> (newval));
+            Grob_array *new_arr = unsmob<Grob_array> (newval);
+            new_arr->filter_map_assign (*grob_array, substitute_grob);
           }
         else
           {
index 8fc60387bcaee89dec9fde986e04b0fa796f4e51..ec0ee43e1895f92eb21f16f616110f5e1ed2ed0e 100644 (file)
@@ -39,18 +39,6 @@ Grob_array::Grob_array ()
   ordered_ = true;
 }
 
-vector<Grob *> &
-Grob_array::array_reference ()
-{
-  return grobs_;
-}
-
-vector<Grob *> 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<Grob *> 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?";
index e3963f019dba3451e7961e5d8fcc6fb87db7bfcf..1a755fe66196c2bdbbf301c2217a068d06a010b0 100644 (file)
@@ -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<Grob *> const &src);
-  vector<Grob *> &array_reference ();
-  vector<Grob *> const &array () const;
+  void set_array (vector<Grob *> const &src) { grobs_ = src; }
+  vector<Grob *> &array_reference () { return grobs_; }
+  vector<Grob *> 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 *));
 };
 
 
index 3ea5a89f0538a37b236c412e9744ba5a378ad61f..da3807c31d6f4ddb33fb75edf69c24ec3baf8175 100644 (file)
@@ -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> (grob);
 
-  SCM bbm = me->get_object ("bounded-by-me");
-  Grob_array *ga = unsmob<Grob_array> (bbm);
-  if (!ga)
-    return SCM_UNSPECIFIED;
-
-  vector<Grob *> &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<Grob_array> (me->get_object ("bounded-by-me")))
+    ga->filter (grob_is_live);
 
   return SCM_UNSPECIFIED;
 }
index d78d8d619c1edd78504f2d21339dc9585f6b8c58..745c23dbec0d982ab59e1d5d3aec275d0ae86bcd 100644 (file)
@@ -41,13 +41,8 @@ Pure_from_neighbor_interface::calc_pure_relevant_grobs (SCM smob)
   vector<Grob *> new_elts;
   new_elts.insert (new_elts.end (), elts.begin (), elts.end ());
 
-  SCM neighbors_scm = me->get_object ("neighbors");
-  if (unsmob<Grob_array> (neighbors_scm))
-    {
-      vector<Grob *> &arr
-        = unsmob<Grob_array> (neighbors_scm)->array_reference ();
-      arr = new_elts;
-    }
+  if (Grob_array *a = unsmob<Grob_array> (me->get_object ("neighbors")))
+    a->set_array (new_elts);
 
   return Axis_group_interface::internal_calc_pure_relevant_grobs (me, "neighbors");
 }
index a11a30258e8f3ae57daf500a19a171a5421a5f6b..5f95e5d4d659203dbee12d58aa7d59c3aa69dd47 100644 (file)
@@ -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<Grob_array> (encompass_scm))
-    {
-      vector<Grob *> &arr
-        = unsmob<Grob_array> (encompass_scm)->array_reference ();
-      arr = new_encompasses;
-    }
+  if (Grob_array *a = unsmob<Grob_array> (me->get_object ("encompass-objects")))
+    a->set_array (new_encompasses);
 }
 
 Bezier
index 4a18ab52b7fd8c8b61d153d182fe79afad490208..0551b85cbccda5286e770fdc238722edda48aec7 100644 (file)
@@ -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 <Grob *> &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 ());