From: Daniel Arndt Date: Wed, 24 Jan 2018 08:50:45 +0000 (+0100) Subject: Check contiguity of iterators X-Git-Tag: v9.0.0-rc1~521^2 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8023b6eacf94d376e0cf7bbff0187bc416445f74;p=dealii.git Check contiguity of iterators --- diff --git a/include/deal.II/base/array_view.h b/include/deal.II/base/array_view.h index abbc7c308c..6c3259179c 100644 --- a/include/deal.II/base/array_view.h +++ b/include/deal.II/base/array_view.h @@ -573,6 +573,24 @@ make_array_view (std::vector &vector, return ArrayView (&vector[starting_index], size_of_view); } +#ifndef DOXYGEN +namespace internal +{ + namespace ArrayViewHelper + { + template + bool is_contiguous(const Iterator &first, const Iterator &last) + { + const auto n = std::distance(first, last); + for (typename std::decay::type i = 0; i < n; ++i) + if (*(std::next(first, i)) != *(std::next(std::addressof(*first), i))) + return false; + return true; + } + } +} +#endif + /** * Create an ArrayView that takes a pair of iterators as arguments. The type @@ -585,6 +603,8 @@ make_array_view (std::vector &vector, * boost::container::small_vector or std::vector and * will not work correctly with, e.g., * boost::container::stable_vector or std::deque. + * In debug mode, we check that the provided iterators represent contiguous + * memory indeed. * * @relates ArrayView */ @@ -597,6 +617,8 @@ make_array_view (const Iterator begin, const Iterator end) "The provided iterator should be a random access iterator."); Assert(begin <= end, ExcMessage("The beginning of the array view should be before the end.")); + Assert(internal::ArrayViewHelper::is_contiguous(begin, end), + ExcMessage("The provided range isn't contiguous in memory!")); // the reference type, not the value type, knows the constness of the iterator return ArrayView::reference>::type> diff --git a/source/lac/vector.cc b/source/lac/vector.cc index a1f97a6787..0f1c13a152 100644 --- a/source/lac/vector.cc +++ b/source/lac/vector.cc @@ -22,6 +22,7 @@ DEAL_II_NAMESPACE_OPEN // instantiate for integers: template class Vector; template Vector &Vector::operator= (const dealii::Vector &); +template bool Vector::operator== (dealii::Vector const &) const; template void Vector::reinit(const Vector &, const bool); diff --git a/tests/base/array_view_13.cc b/tests/base/array_view_13.cc new file mode 100644 index 0000000000..d7447ec727 --- /dev/null +++ b/tests/base/array_view_13.cc @@ -0,0 +1,60 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2017 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. +// +// --------------------------------------------------------------------- + + +// test for class ArrayView + +#include "../tests.h" + +#include + +template +void test (const T &t) +{ + try + { + make_array_view(std::begin(t), std::end(t)); + } + catch (ExceptionBase &e) + { + deallog << e.get_exc_name() << std::endl; + } +} + +int main() +{ + deal_II_exceptions::disable_abort_on_exception(); + initlog(); + + auto d1 = std::deque(2); + auto d2 = std::deque(4000); + int c[] = { 1, 2, 3 }; + auto a = std::array {{ 1, 2, 3 }}; + auto s = std::string {"Hello world!"}; + auto v = std::vector { 1, 2, 3, }; + + deallog << "Testing std::deque(2)" << std::endl; + test(d1); + deallog << "Testing std::deque(4000)" << std::endl; + test(d2); + deallog << "Testing int c[3]{1,2,3}" << std::endl; + test(c); + deallog << "Testing std::array {{ 1,2,3}}" << std::endl; + test(a); + deallog << "Testing std::string {\"Hello world!\"}" << std::endl; + test(s); + deallog << "Testing std::vector{1,2,3}" << std::endl; + test(v); +} diff --git a/tests/base/array_view_13.debug.output b/tests/base/array_view_13.debug.output new file mode 100644 index 0000000000..27b5e0af5e --- /dev/null +++ b/tests/base/array_view_13.debug.output @@ -0,0 +1,8 @@ + +DEAL::Testing std::deque(2) +DEAL::Testing std::deque(4000) +DEAL::ExcMessage("The provided range isn't contiguous in memory!") +DEAL::Testing int c[3]{1,2,3} +DEAL::Testing std::array {{ 1,2,3}} +DEAL::Testing std::string {"Hello world!"} +DEAL::Testing std::vector{1,2,3}