aboutsummaryrefslogtreecommitdiff
path: root/libstdc++-v3/testsuite/ext/pb_assoc/example/tree_intervals.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libstdc++-v3/testsuite/ext/pb_assoc/example/tree_intervals.cc')
-rw-r--r--libstdc++-v3/testsuite/ext/pb_assoc/example/tree_intervals.cc260
1 files changed, 260 insertions, 0 deletions
diff --git a/libstdc++-v3/testsuite/ext/pb_assoc/example/tree_intervals.cc b/libstdc++-v3/testsuite/ext/pb_assoc/example/tree_intervals.cc
new file mode 100644
index 00000000000..494ab5d55f5
--- /dev/null
+++ b/libstdc++-v3/testsuite/ext/pb_assoc/example/tree_intervals.cc
@@ -0,0 +1,260 @@
+// -*- C++ -*-
+
+// Copyright (C) 2005 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library 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 2, or (at your option)
+// any later version.
+
+// This library 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 this library; see the file COPYING. If not, write to the Free
+// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+// USA.
+
+// As a special exception, you may use this file as part of a free software
+// library without restriction. Specifically, if other files instantiate
+// templates or use macros or inline functions from this file, or you compile
+// this file and link it with other files to produce an executable, this
+// file does not by itself cause the resulting executable to be covered by
+// the GNU General Public License. This exception does not however
+// invalidate any other reasons why the executable file might be covered by
+// the GNU General Public License.
+
+// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
+
+// Permission to use, copy, modify, sell, and distribute this software
+// is hereby granted without fee, provided that the above copyright
+// notice appears in all copies, and that both that copyright notice and
+// this permission notice appear in supporting documentation. None of
+// the above authors, nor IBM Haifa Research Laboratories, make any
+// representation about the suitability of this software for any
+// purpose. It is provided "as is" without express or implied warranty.
+
+/*
+ * @file tree_set_intervals_example.cpp
+ * An example showing how to augment a trees to support operations involving
+ * line intervals.
+ */
+
+// For ov_tree_set
+#include <ext/pb_assoc/assoc_cntnr.hpp>
+// For assert
+#include <cassert>
+// For NULL
+#include <cstdlib>
+
+/*
+ * Following are definitions of line intervals and functors operating on them.
+ * As the purpose of this example is node invariants, and not
+ * computational-geometry algorithms per-se, some simplifications are made
+ *(e.g., intervals are defined by unsigned integers, and not by*a parameterized type, data members are public, etc.).
+ */
+
+/*
+ * An interval of unsigned integers.
+ **/
+struct interval
+{
+ /*
+ * Constructor.
+ * @param start [i] - Start point.
+ * @param end [i] - End point.
+ */
+ interval(unsigned int start, unsigned int end) : m_start(start),
+ m_end(end)
+ {
+ assert(start <= end);
+ }
+
+ /*
+ * Comparison predicate.
+ * @param r_rhs [i] - Right-hand object with which to compare.
+ **/
+ bool
+ operator<(const interval& r_rhs) const
+ {
+ if (m_start != r_rhs.m_start)
+ return (m_start < r_rhs.m_start);
+
+ return (m_end < r_rhs.m_end);
+ }
+
+ /*
+ * Start point.
+ */
+ unsigned int m_start;
+
+ /*
+ * End point.
+ **/
+ unsigned int m_end;
+};
+
+struct intervals_node_updator;
+
+template<class Cntnr>
+bool
+overlaps(const Cntnr& r_c, const interval& r_interval);
+
+/*
+ * The entry of the set. It includes an interval and the
+ * maximal endpoint of the intervals in its subtree.
+ */
+struct entry
+{
+ // Constructor. The maximal endpoint is set to the endpoint
+ explicit entry(unsigned int start, unsigned int end) : m_interval(start, end),
+ m_max_endpoint(end)
+ { }
+
+ // Compares two entries by their intervals.
+ inline bool
+ operator<(const entry& r_rhs) const
+ {
+ return (m_interval < r_rhs.m_interval);
+ }
+
+ // An interval
+ interval m_interval;
+
+private:
+ // The maximal endpoint of the intervals in its subtree.
+ mutable unsigned int m_max_endpoint;
+
+ friend struct intervals_node_updator;
+
+ template<class Cntnr>
+ friend bool
+ overlaps(const Cntnr& r_c, const interval& r_interval);
+
+};
+
+/*
+ * Functor updating maximal endpoints of entries.
+ * Algorithm taken from "Introduction to Algorithms" by Cormen, Leiserson,
+ * and Rivest.
+ */
+struct intervals_node_updator
+{
+ inline void
+ operator()(const entry* p_entry, const entry* p_l_child_entry, const entry* p_r_child_entry)
+ {
+ /* The left maximal endpoint is 0 if there is no left child.
+ */
+ const unsigned int l_max_endpoint =(p_l_child_entry == NULL)? 0 : p_l_child_entry->m_max_endpoint;
+
+ /* The right maximal endpoint is 0 if there is no right child.
+ */
+ const unsigned int r_max_endpoint =(p_r_child_entry == NULL)? 0 : p_r_child_entry->m_max_endpoint;
+
+ p_entry->m_max_endpoint = std::max(p_entry->m_interval.m_end,
+ std::max<unsigned int>(l_max_endpoint, r_max_endpoint));
+ }
+};
+
+/*
+ * Checks whether a set of intervals contains at least one interval
+ * overlapping some interval.
+ * Algorithm taken from "Introduction to Algorithms" by Cormen, Leiserson,
+ * and Rivest.
+ **/
+template<class Cntnr>
+bool
+overlaps(const Cntnr& r_c, const interval& r_interval)
+{
+ typedef typename Cntnr::const_iterator intr_set_const_it;
+
+ typedef typename Cntnr::const_node_iterator intr_set_const_node_it;
+
+ intr_set_const_node_it node_it = r_c.node_begin();
+
+ while (node_it != r_c.node_end())
+ {
+ // Check whether r_interval overlaps the current interval.
+
+ intr_set_const_it it =* node_it;
+
+ if (r_interval.m_end >= it->m_interval.m_start&&
+ r_interval.m_start <= it->m_interval.m_end)
+ return (true);
+
+ intr_set_const_node_it l_node_it = node_it.l_child();
+
+ const unsigned int l_max_endpoint =(l_node_it == r_c.node_end())?
+ 0 : (*l_node_it)->m_max_endpoint;
+
+ if (l_max_endpoint >= r_interval.m_start)
+ node_it = l_node_it;
+ else
+ node_it = node_it.r_child();
+ }
+
+ return (false);
+}
+
+template<class Cntnr>
+void
+some_op_sequence(Cntnr c)
+{
+ // Insert some entries.
+
+ c.insert(entry(0, 100));
+ c.insert(entry(150, 160));
+ c.insert(entry(300, 1000));
+ c.insert(entry(10000, 100000));
+ c.insert(entry(200, 100200));
+
+ // Test overlaps.
+
+ // Overlaps 150 - 160
+ assert(overlaps(c, interval(145, 165)) == true);
+ // Overlaps 150 - 160
+ assert(overlaps(c, interval(145, 155)) == true);
+ assert(overlaps(c, interval(165, 175)) == false);
+ assert(overlaps(c, interval(100201, 100203)) == false);
+
+ // Erase an entry.
+
+ entry e(150, 160);
+
+ c.erase(e);
+
+ // Test overlaps again.
+
+ assert(overlaps(c, interval(145, 165)) == false);
+ assert(overlaps(c, interval(165, 175)) == false);
+ assert(overlaps(c, interval(0, 300000)) == true);
+}
+
+int
+main()
+{
+ some_op_sequence(pb_assoc::tree_assoc_cntnr<
+ entry,
+ pb_assoc::null_data_type,
+ std::less<entry>,
+ pb_assoc::ov_tree_ds_tag,
+ intervals_node_updator>());
+
+ some_op_sequence(pb_assoc::tree_assoc_cntnr<
+ entry,
+ pb_assoc::null_data_type,
+ std::less<entry>,
+ pb_assoc::rb_tree_ds_tag,
+ intervals_node_updator>());
+
+ some_op_sequence(pb_assoc::tree_assoc_cntnr<
+ entry,
+ pb_assoc::null_data_type,
+ std::less<entry>,
+ pb_assoc::splay_tree_ds_tag,
+ intervals_node_updator>());
+}
+