From 14d966b2ccaef0074e2b0c1a812c3bfc49f0d0e3 Mon Sep 17 00:00:00 2001 From: Rene Gassmoeller Date: Thu, 3 Nov 2016 18:13:08 -0600 Subject: [PATCH] Add IndexSet::pop_front, pop_back, and is_empty --- include/deal.II/base/index_set.h | 26 ++++++++++++++++++++ source/base/index_set.cc | 38 +++++++++++++++++++++++++++++ tests/base/index_set_25.cc | 41 ++++++++++++++++++++++++++++++++ tests/base/index_set_25.output | 6 +++++ tests/base/index_set_26.cc | 41 ++++++++++++++++++++++++++++++++ tests/base/index_set_26.output | 6 +++++ 6 files changed, 158 insertions(+) create mode 100644 tests/base/index_set_25.cc create mode 100644 tests/base/index_set_25.output create mode 100644 tests/base/index_set_26.cc create mode 100644 tests/base/index_set_26.output diff --git a/include/deal.II/base/index_set.h b/include/deal.II/base/index_set.h index 34400387a1..20261c4cb2 100644 --- a/include/deal.II/base/index_set.h +++ b/include/deal.II/base/index_set.h @@ -217,6 +217,12 @@ public: */ bool is_contiguous () const; + /** + * Return whether the index set stored by this object contains no elements. + * This is similar, but faster than checking n_elements() == 0. + */ + bool is_empty () const; + /** * Return whether the IndexSets are ascending with respect to MPI process * number and 1:1, i.e., each index is contained in exactly one IndexSet @@ -315,6 +321,18 @@ public: */ void subtract_set (const IndexSet &other); + /** + * Removes and returns the last element of the last range. + * Throws an exception if the IndexSet is empty. + */ + size_type pop_back (); + + /** + * Removes and returns the first element of the first range. + * Throws an exception if the IndexSet is empty. + */ + size_type pop_front (); + /** * Fills the given vector with all indices contained in this IndexSet. */ @@ -1519,6 +1537,14 @@ IndexSet::is_contiguous () const } +inline +bool +IndexSet::is_empty () const +{ + return ranges.empty(); +} + + inline IndexSet::size_type diff --git a/source/base/index_set.cc b/source/base/index_set.cc index 6126766db5..9af19f060d 100644 --- a/source/base/index_set.cc +++ b/source/base/index_set.cc @@ -341,6 +341,44 @@ IndexSet::subtract_set (const IndexSet &other) +IndexSet::size_type +IndexSet::pop_back () +{ + Assert(ranges.size() != 0, + ExcMessage("pop_back() failed, because this IndexSet contains no entries.")); + + const size_type index = ranges.back().end-1; + --ranges.back().end; + + if (ranges.back().begin == ranges.back().end) + ranges.pop_back(); + + return index; +} + + + +IndexSet::size_type +IndexSet::pop_front () +{ + Assert(ranges.size() != 0, + ExcMessage("pop_front() failed, because this IndexSet contains no entries.")); + + const size_type index = ranges.front().begin; + ++ranges.front().begin; + + if (ranges.front().begin == ranges.front().end) + ranges.erase(ranges.begin()); + + // We have to set this in any case, because nth_index_in_set is not longer + // up to date for all but the first range + is_compressed = false; + + return index; +} + + + void IndexSet::add_indices(const IndexSet &other, const unsigned int offset) diff --git a/tests/base/index_set_25.cc b/tests/base/index_set_25.cc new file mode 100644 index 0000000000..6f507a2feb --- /dev/null +++ b/tests/base/index_set_25.cc @@ -0,0 +1,41 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2010 - 2015 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +// Check that pop_front() for `IndexSet` works properly + +#include "../tests.h" +#include + +#include +#include + +int main() +{ + std::ofstream logfile("output"); + deallog.attach(logfile); + + IndexSet is1(10); + is1.add_range(0, 2); + is1.add_range(5,8); + + deallog << is1.n_elements() << ", " << is1.pop_front() << std::endl; + deallog << is1.n_elements() << ", " << is1.pop_front() << std::endl; + deallog << is1.n_elements() << ", " << is1.pop_front() << std::endl; + + is1.add_index(1); + + deallog << is1.n_elements() << ", " << is1.pop_front() << std::endl; + deallog << is1.n_elements() << ", " << is1.pop_front() << std::endl; +} diff --git a/tests/base/index_set_25.output b/tests/base/index_set_25.output new file mode 100644 index 0000000000..850d440266 --- /dev/null +++ b/tests/base/index_set_25.output @@ -0,0 +1,6 @@ + +DEAL::4, 0 +DEAL::3, 1 +DEAL::2, 5 +DEAL::2, 1 +DEAL::1, 6 diff --git a/tests/base/index_set_26.cc b/tests/base/index_set_26.cc new file mode 100644 index 0000000000..528a4f3d4d --- /dev/null +++ b/tests/base/index_set_26.cc @@ -0,0 +1,41 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2010 - 2015 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + +// Check that pop_back() for `IndexSet` works properly + +#include "../tests.h" +#include + +#include +#include + +int main() +{ + std::ofstream logfile("output"); + deallog.attach(logfile); + + IndexSet is1(10); + is1.add_range(0, 2); + is1.add_range(5,8); + + deallog << is1.n_elements() << ", " << is1.pop_back() << std::endl; + deallog << is1.n_elements() << ", " << is1.pop_back() << std::endl; + deallog << is1.n_elements() << ", " << is1.pop_back() << std::endl; + + is1.add_index(9); + + deallog << is1.n_elements() << ", " << is1.pop_back() << std::endl; + deallog << is1.n_elements() << ", " << is1.pop_back() << std::endl; +} diff --git a/tests/base/index_set_26.output b/tests/base/index_set_26.output new file mode 100644 index 0000000000..1da81923f7 --- /dev/null +++ b/tests/base/index_set_26.output @@ -0,0 +1,6 @@ + +DEAL::4, 7 +DEAL::3, 6 +DEAL::2, 5 +DEAL::2, 9 +DEAL::1, 1 -- 2.39.5