From 73fe929811724184584c4f5dbe35b07d1509e405 Mon Sep 17 00:00:00 2001 From: Christopher Lackner Date: Tue, 30 Jul 2019 13:38:42 +0200 Subject: [PATCH 1/2] use NETGEN_CHECK_RANGE macro in array --- libsrc/core/array.hpp | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/libsrc/core/array.hpp b/libsrc/core/array.hpp index 0dbc463c..1f72113c 100644 --- a/libsrc/core/array.hpp +++ b/libsrc/core/array.hpp @@ -9,27 +9,14 @@ #include "archive.hpp" +#include "exception.hpp" #include "localheap.hpp" #include "utils.hpp" -#ifdef DEBUG -#define CHECK_RANGE -#endif - namespace ngcore { using std::ostream; - /** - Exception thrown by array range check. - Only thrown when compiled with RANGE_CHECK - */ - class ArrayRangeException : public Exception - { - public: - ArrayRangeException () : Exception("ArrayRangeException\n") { ; } - }; - template class Tuple { public: @@ -392,7 +379,7 @@ namespace ngcore Array represented by size and data-pointer. No memory allocation and deallocation, must be provided by user. Helper functions for printing. - Optional range check by macro CHECK_RANGE + Optional range check by macro NETGEN_CHECK_RANGE */ template class FlatArray : public BaseArrayObject > @@ -485,13 +472,10 @@ namespace ngcore return *this; } - /// Access array. range check by macro CHECK_RANGE + /// Access array. range check by macro NETGEN_CHECK_RANGE NETGEN_INLINE T & operator[] (size_t i) const { -#ifdef CHECK_RANGE - if (i < 0 || i >= size) - throw RangeException ("FlatArray::operator[]", i, 0, size-1); -#endif + NETGEN_CHECK_RANGE(i,0,size-1); return data[i]; } @@ -509,13 +493,10 @@ namespace ngcore // { return CArray (data+pos); } NETGEN_INLINE T * operator+ (size_t pos) const { return data+pos; } - /// access last element. check by macro CHECK_RANGE + /// access last element. check by macro NETGEN_CHECK_RANGE T & Last () const { -#ifdef CHECK_RANGE - if (!size) - throw Exception ("Array should not be empty"); -#endif + NETGEN_CHECK_RANGE(0,size-1,size-1); return data[size-1]; } @@ -857,10 +838,7 @@ namespace ngcore /// Delete element i. Move last element to position i. NETGEN_INLINE void DeleteElement (size_t i) { -#ifdef CHECK_RANGE - // RangeCheck (i); -#endif - + NETGEN_CHECK_RANGE(i,0,size-1); data[i] = std::move(data[size-1]); size--; } @@ -878,9 +856,7 @@ namespace ngcore /// Delete last element. NETGEN_INLINE void DeleteLast () { -#ifdef CHECK_RANGE - // CheckNonEmpty(); -#endif + NETGEN_CHECK_RANGE(0,size-1,size-1); size--; } From 9f32a5c3ad9a495b241bc33384bc63038502b750 Mon Sep 17 00:00:00 2001 From: Christopher Lackner Date: Mon, 5 Aug 2019 12:48:08 +0200 Subject: [PATCH 2/2] fix range check, add some tests --- libsrc/core/array.hpp | 8 ++++---- libsrc/core/exception.hpp | 8 ++++---- tests/catch/array.cpp | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 tests/catch/array.cpp diff --git a/libsrc/core/array.hpp b/libsrc/core/array.hpp index 1f72113c..2a613b21 100644 --- a/libsrc/core/array.hpp +++ b/libsrc/core/array.hpp @@ -475,7 +475,7 @@ namespace ngcore /// Access array. range check by macro NETGEN_CHECK_RANGE NETGEN_INLINE T & operator[] (size_t i) const { - NETGEN_CHECK_RANGE(i,0,size-1); + NETGEN_CHECK_RANGE(i,0,size); return data[i]; } @@ -496,7 +496,7 @@ namespace ngcore /// access last element. check by macro NETGEN_CHECK_RANGE T & Last () const { - NETGEN_CHECK_RANGE(0,size-1,size-1); + NETGEN_CHECK_RANGE(size-1,0,size); return data[size-1]; } @@ -838,7 +838,7 @@ namespace ngcore /// Delete element i. Move last element to position i. NETGEN_INLINE void DeleteElement (size_t i) { - NETGEN_CHECK_RANGE(i,0,size-1); + NETGEN_CHECK_RANGE(i,0,size); data[i] = std::move(data[size-1]); size--; } @@ -856,7 +856,7 @@ namespace ngcore /// Delete last element. NETGEN_INLINE void DeleteLast () { - NETGEN_CHECK_RANGE(0,size-1,size-1); + NETGEN_CHECK_RANGE(size-1,0,size); size--; } diff --git a/libsrc/core/exception.hpp b/libsrc/core/exception.hpp index 35359e65..68e7c073 100644 --- a/libsrc/core/exception.hpp +++ b/libsrc/core/exception.hpp @@ -55,7 +55,7 @@ namespace ngcore int ind, int imin, int imax) : Exception("") { std::stringstream str; - str << where << ": index " << ind << " out of range [" << imin << "," << imax << "]\n"; + str << where << ": index " << ind << " out of range [" << imin << "," << imax << ")\n"; Append (str.str()); } @@ -80,9 +80,9 @@ namespace ngcore #define NG_EXCEPTION(s) ngcore::Exception(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t"+std::string(s)) #ifdef NETGEN_ENABLE_CHECK_RANGE -#define NETGEN_CHECK_RANGE(value, min, max) \ - { if ((value)<(min) || (value)>=(max)) \ - throw ngcore::RangeException(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", (value), (min), (max)); } +#define NETGEN_CHECK_RANGE(value, min, max_plus_one) \ + { if ((value)<(min) || (value)>=(max_plus_one)) \ + throw ngcore::RangeException(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", (value), (min), (max_plus_one)); } #else // NETGEN_ENABLE_CHECK_RANGE #define NETGEN_CHECK_RANGE(value, min, max) #endif // NETGEN_ENABLE_CHECK_RANGE diff --git a/tests/catch/array.cpp b/tests/catch/array.cpp new file mode 100644 index 00000000..471806c0 --- /dev/null +++ b/tests/catch/array.cpp @@ -0,0 +1,37 @@ + +#include "catch.hpp" +#include +using namespace ngcore; +using namespace std; + + +TEST_CASE("Array") +{ + Array array; +#ifdef DEBUG + CHECK_THROWS_AS(array[0], RangeException); + CHECK_THROWS_AS(array.DeleteLast(), RangeException); + CHECK_THROWS_AS(array.Last(), RangeException); +#endif // DEBUG + Array a_initlst = { 1., 2., 3.}; + CHECK(a_initlst[1] == 2.); + CHECK(a_initlst.size() == 3); + FlatArray fa_a = a_initlst; + CHECK(typeid(fa_a) == typeid(FlatArray)); + CHECK(fa_a.size() == 3); + CHECK(a.Last() == 3.); + a.DeleteLast(); + CHECK(a.Last() == 2. && a.Size() == 2); +#ifdef DEBUG + CHECK_THROWS_AS(fa_a[5], RangeException); +#endif // DEBUG + Array b = Array(4); + b = 2; + int count = 0; + for(auto val : b) + { + count++; + CHECK(val == 2); + } + CHECK(count == 4); +}