Improvements to typed_splay_tree
authorDavid Malcolm <dmalcolm@redhat.com>
Fri, 2 Sep 2016 15:22:21 +0000 (15:22 +0000)
committerDavid Malcolm <dmalcolm@gcc.gnu.org>
Fri, 2 Sep 2016 15:22:21 +0000 (15:22 +0000)
This patch adds foreach, max and min methods to
class typed_splay_tree, along with the start of a selftest
suite.

gcc/ChangeLog:
* Makefile.in (OBJS): Add typed-splay-tree.o.
* selftest-run-tests.c (selftest::run_tests): Call
typed_splay_tree_c_tests.
* selftest.h (typed_splay_tree_c_tests): New decl.
* typed-splay-tree.c: New file.
* typed-splay-tree.h (typed_splay_tree::foreach_fn): New typedef.
(typed_splay_tree::max): New method.
(typed_splay_tree::min): New method.
(typed_splay_tree::foreach): New method.
(typed_splay_tree::closure): New struct.
(typed_splay_tree::inner_foreach_fn): New function.

From-SVN: r239958

gcc/ChangeLog
gcc/Makefile.in
gcc/selftest-run-tests.c
gcc/selftest.h
gcc/typed-splay-tree.c [new file with mode: 0644]
gcc/typed-splay-tree.h

index 7e1a9514aabce75e79722a95ac4ed7b0a3443901..cae775f393d2b483901f75bc86043a689ea5d666 100644 (file)
@@ -1,3 +1,17 @@
+2016-09-02  David Malcolm  <dmalcolm@redhat.com>
+
+       * Makefile.in (OBJS): Add typed-splay-tree.o.
+       * selftest-run-tests.c (selftest::run_tests): Call
+       typed_splay_tree_c_tests.
+       * selftest.h (typed_splay_tree_c_tests): New decl.
+       * typed-splay-tree.c: New file.
+       * typed-splay-tree.h (typed_splay_tree::foreach_fn): New typedef.
+       (typed_splay_tree::max): New method.
+       (typed_splay_tree::min): New method.
+       (typed_splay_tree::foreach): New method.
+       (typed_splay_tree::closure): New struct.
+       (typed_splay_tree::inner_foreach_fn): New function.
+
 2016-09-02  Prathamesh Kulkarni  <prathamesh.kulkarni@linaro.org>
 
        * ipa-cp.c (ipcp_store_bits_results): Change option name from
index eb5ab61f36c491cced9b74c4a0b0689fe736e098..b38a0c15998ccc35d49884b8fa4dc21ebc9b7a25 100644 (file)
@@ -1542,6 +1542,7 @@ OBJS = \
        tree-vectorizer.o \
        tree-vrp.o \
        tree.o \
+       typed-splay-tree.o \
        valtrack.o \
        value-prof.o \
        var-tracking.o \
index 6453e31498299da90e5353a87344a63660148dda..e20bbd0f568fb16c48d074340ca9c946de40cd2a 100644 (file)
@@ -56,6 +56,7 @@ selftest::run_tests ()
   ggc_tests_c_tests ();
   sreal_c_tests ();
   fibonacci_heap_c_tests ();
+  typed_splay_tree_c_tests ();
 
   /* Mid-level data structures.  */
   input_c_tests ();
index 47d735033707063221f3cf4ddd8b6f55c375ef04..54a33f903e2374992455853c6844980cd44b5167 100644 (file)
@@ -166,6 +166,7 @@ extern void selftest_c_tests ();
 extern void spellcheck_c_tests ();
 extern void spellcheck_tree_c_tests ();
 extern void sreal_c_tests ();
+extern void typed_splay_tree_c_tests ();
 extern void tree_c_tests ();
 extern void tree_cfg_c_tests ();
 extern void vec_c_tests ();
diff --git a/gcc/typed-splay-tree.c b/gcc/typed-splay-tree.c
new file mode 100644 (file)
index 0000000..33992c1
--- /dev/null
@@ -0,0 +1,79 @@
+/* Selftests for typed-splay-tree.h.
+   Copyright (C) 2016 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation; either version 3, or (at your option) any later
+version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "typed-splay-tree.h"
+#include "selftest.h"
+
+#if CHECKING_P
+
+namespace selftest {
+
+/* Callback for use by test_str_to_int.  */
+
+static int
+append_cb (const char *, int value, void *user_data)
+{
+  auto_vec <int> *vec = (auto_vec <int> *)user_data;
+  vec->safe_push (value);
+  return 0;
+}
+
+/* Test of typed_splay_tree <const char *, int>.  */
+
+static void
+test_str_to_int ()
+{
+  typed_splay_tree <const char *, int> t (strcmp, NULL, NULL);
+
+  t.insert ("a", 1);
+  t.insert ("b", 2);
+  t.insert ("c", 3);
+
+  ASSERT_EQ (1, t.lookup ("a"));
+  ASSERT_EQ (2, t.lookup ("b"));
+  ASSERT_EQ (3, t.lookup ("c"));
+
+  ASSERT_EQ (2, t.predecessor ("c"));
+  ASSERT_EQ (3, t.successor ("b"));
+  ASSERT_EQ (1, t.min ());
+  ASSERT_EQ (3, t.max ());
+
+  /* Test foreach by appending to a vec, and verifying the vec.  */
+  auto_vec <int> v;
+  t.foreach (append_cb, &v);
+  ASSERT_EQ (3, v.length ());
+  ASSERT_EQ (1, v[0]);
+  ASSERT_EQ (2, v[1]);
+  ASSERT_EQ (3, v[2]);
+}
+
+/* Run all of the selftests within this file.  */
+
+void
+typed_splay_tree_c_tests ()
+{
+  test_str_to_int ();
+}
+
+} // namespace selftest
+
+#endif /* #if CHECKING_P */
index 9dd96d610293411d995a859bc95e0ad686691560..7b8afef2b1de11d98f79d482e4d82a9a397ba7f5 100644 (file)
@@ -33,6 +33,7 @@ class typed_splay_tree
   typedef int (*compare_fn) (key_type, key_type);
   typedef void (*delete_key_fn) (key_type);
   typedef void (*delete_value_fn) (value_type);
+  typedef int (*foreach_fn) (key_type, value_type, void *);
 
   typed_splay_tree (compare_fn,
                    delete_key_fn,
@@ -43,8 +44,23 @@ class typed_splay_tree
   value_type predecessor (key_type k);
   value_type successor (key_type k);
   void insert (key_type k, value_type v);
+  value_type max ();
+  value_type min ();
+  int foreach (foreach_fn, void *);
 
  private:
+  /* Helper type for typed_splay_tree::foreach.  */
+  struct closure
+  {
+    closure (foreach_fn outer_cb, void *outer_user_data)
+    : m_outer_cb (outer_cb), m_outer_user_data (outer_user_data) {}
+
+    foreach_fn m_outer_cb;
+    void *m_outer_user_data;
+  };
+
+  static int inner_foreach_fn (splay_tree_node node, void *user_data);
+
   static value_type node_to_value (splay_tree_node node);
 
  private:
@@ -120,6 +136,52 @@ typed_splay_tree<KEY_TYPE, VALUE_TYPE>::insert (key_type key,
                     (splay_tree_value)value);
 }
 
+/* Get the value with maximal key.  */
+
+template <typename KEY_TYPE, typename VALUE_TYPE>
+inline VALUE_TYPE
+typed_splay_tree<KEY_TYPE, VALUE_TYPE>::max ()
+{
+  return node_to_value (splay_tree_max (m_inner));
+}
+
+/* Get the value with minimal key.  */
+
+template <typename KEY_TYPE, typename VALUE_TYPE>
+inline VALUE_TYPE
+typed_splay_tree<KEY_TYPE, VALUE_TYPE>::min ()
+{
+  return node_to_value (splay_tree_min (m_inner));
+}
+
+/* Call OUTER_CB, passing it the OUTER_USER_DATA, for every node,
+   following an in-order traversal.  If OUTER_CB ever returns a non-zero
+   value, the iteration ceases immediately, and the value is returned.
+   Otherwise, this function returns 0.  */
+
+template <typename KEY_TYPE, typename VALUE_TYPE>
+inline int
+typed_splay_tree<KEY_TYPE, VALUE_TYPE>::foreach (foreach_fn outer_cb,
+                                                void *outer_user_data)
+{
+  closure c (outer_cb, outer_user_data);
+
+  return splay_tree_foreach (m_inner, inner_foreach_fn, &c);
+}
+
+/* Helper function for typed_splay_tree::foreach.  */
+
+template <typename KEY_TYPE, typename VALUE_TYPE>
+int
+typed_splay_tree<KEY_TYPE, VALUE_TYPE>::inner_foreach_fn (splay_tree_node node,
+                                                         void *user_data)
+{
+  closure *c = (closure *)user_data;
+
+  return c->m_outer_cb ((KEY_TYPE)node->key, (VALUE_TYPE)node->value,
+                       c->m_outer_user_data);
+}
+
 /* Internal function for converting from splay_tree_node to
    VALUE_TYPE.  */
 template <typename KEY_TYPE, typename VALUE_TYPE>