*/
bool is_element (const unsigned int index) const;
+ /**
+ * Return whether the index set
+ * stored by this object defines
+ * a contiguous range. This is
+ * true also if no indices are
+ * stored at all.
+ */
+ bool is_contiguous () const;
+
+ /**
+ * Compress the internal
+ * representation by merging
+ * individual elements with
+ * contiguous ranges, etc. This
+ * function does not have any
+ * external effect.
+ */
+ void compress () const;
+
private:
/**
* A type that denotes an index
* A set of contiguous ranges of
* indices that make up (part of)
* this index set.
+ *
+ * The variable is marked
+ * "mutable" so that it can be
+ * changed by compress(), though
+ * this of course doesn't change
+ * anything about the external
+ * representation of this index
+ * set.
*/
- std::set<ContiguousRange, RangeComparison> contiguous_ranges;
+ mutable std::set<ContiguousRange, RangeComparison> contiguous_ranges;
/**
* A set of individual indices
* that make up (part of) this
* index set, together with the
* contiguous ranges.
+ *
+ * The variable is marked
+ * "mutable" so that it can be
+ * changed by compress(), though
+ * this of course doesn't change
+ * anything about the external
+ * representation of this index
+ * set.
*/
- std::set<unsigned int> individual_indices;
+ mutable std::set<unsigned int> individual_indices;
/**
* The overall size of the index
ExcIndexRange (begin, 0, end));
if (begin != end)
- contiguous_ranges.insert (ContiguousRange(begin,end));
+ {
+ // if it turns out to be a
+ // single element then add that
+ // separately
+ if (end == begin+1)
+ add_index (begin);
+ else
+ contiguous_ranges.insert (ContiguousRange(begin,end));
+ }
}
+inline
+bool
+IndexSet::is_contiguous () const
+{
+ compress ();
+ return ((individual_indices.size() == 0)
+ &&
+ (contiguous_ranges.size() <= 1));
+}
+
+
+
+
DEAL_II_NAMESPACE_CLOSE
--- /dev/null
+//---------------------------------------------------------------------------
+// $Id$
+// Version: $Name$
+//
+// Copyright (C) 2005, 2006, 2008, 2009 by the deal.II authors
+//
+// This file is subject to QPL and may not be distributed
+// without copyright and license information. Please refer
+// to the file deal.II/doc/license.html for the text and
+// further information on this license.
+//
+//---------------------------------------------------------------------------
+
+#include <base/index_set.h>
+
+DEAL_II_NAMESPACE_OPEN
+
+void
+IndexSet::compress () const
+{
+ // first see if any of the
+ // individual entries can be merged
+ // to form contiguous ranges
+ {
+ std::set<unsigned int>::iterator p = individual_indices.begin();
+ while (p != individual_indices.end())
+ {
+ unsigned int n = 0;
+ std::set<unsigned int>::iterator q = p;
+ ++q;
+ while ((q != individual_indices.end())
+ &&
+ (*q == *p+n+1))
+ {
+ ++q;
+ ++n;
+ }
+
+ if (n>0)
+ {
+ const unsigned int range_end = *q;
+
+ // add the new range,
+ // delete the elements of
+ // the range from the set
+ // of individual indices
+ contiguous_ranges.insert (ContiguousRange(*p, *p+n+1));
+ individual_indices.erase (p, q);
+
+ // reset p to the element
+ // past the last
+ p = individual_indices.lower_bound (range_end);
+ }
+ else
+ ++p;
+ }
+ }
+
+
+ // we can roll any of
+ // the individual entries into the
+ // contiguous ranges
+}
+
+
+DEAL_II_NAMESPACE_CLOSE