Merge branch 'array_checkrange' into 'master'

use NETGEN_CHECK_RANGE macro in array

See merge request jschoeberl/netgen!186
This commit is contained in:
Joachim Schöberl 2019-08-05 13:20:25 +00:00
commit 14fe2975e0
3 changed files with 49 additions and 36 deletions

View File

@ -9,27 +9,14 @@
#include "archive.hpp" #include "archive.hpp"
#include "exception.hpp"
#include "localheap.hpp" #include "localheap.hpp"
#include "utils.hpp" #include "utils.hpp"
#ifdef DEBUG
#define CHECK_RANGE
#endif
namespace ngcore namespace ngcore
{ {
using std::ostream; 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 <typename ... ARGS> class Tuple template <typename ... ARGS> class Tuple
{ {
public: public:
@ -392,7 +379,7 @@ namespace ngcore
Array represented by size and data-pointer. Array represented by size and data-pointer.
No memory allocation and deallocation, must be provided by user. No memory allocation and deallocation, must be provided by user.
Helper functions for printing. Helper functions for printing.
Optional range check by macro CHECK_RANGE Optional range check by macro NETGEN_CHECK_RANGE
*/ */
template <class T> template <class T>
class FlatArray : public BaseArrayObject<FlatArray<T> > class FlatArray : public BaseArrayObject<FlatArray<T> >
@ -485,13 +472,10 @@ namespace ngcore
return *this; 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 NETGEN_INLINE T & operator[] (size_t i) const
{ {
#ifdef CHECK_RANGE NETGEN_CHECK_RANGE(i,0,size);
if (i < 0 || i >= size)
throw RangeException ("FlatArray::operator[]", i, 0, size-1);
#endif
return data[i]; return data[i];
} }
@ -509,13 +493,10 @@ namespace ngcore
// { return CArray<T> (data+pos); } // { return CArray<T> (data+pos); }
NETGEN_INLINE T * operator+ (size_t pos) const { return 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 T & Last () const
{ {
#ifdef CHECK_RANGE NETGEN_CHECK_RANGE(size-1,0,size);
if (!size)
throw Exception ("Array should not be empty");
#endif
return data[size-1]; return data[size-1];
} }
@ -857,10 +838,7 @@ namespace ngcore
/// Delete element i. Move last element to position i. /// Delete element i. Move last element to position i.
NETGEN_INLINE void DeleteElement (size_t i) NETGEN_INLINE void DeleteElement (size_t i)
{ {
#ifdef CHECK_RANGE NETGEN_CHECK_RANGE(i,0,size);
// RangeCheck (i);
#endif
data[i] = std::move(data[size-1]); data[i] = std::move(data[size-1]);
size--; size--;
} }
@ -878,9 +856,7 @@ namespace ngcore
/// Delete last element. /// Delete last element.
NETGEN_INLINE void DeleteLast () NETGEN_INLINE void DeleteLast ()
{ {
#ifdef CHECK_RANGE NETGEN_CHECK_RANGE(size-1,0,size);
// CheckNonEmpty();
#endif
size--; size--;
} }

View File

@ -55,7 +55,7 @@ namespace ngcore
int ind, int imin, int imax) : Exception("") int ind, int imin, int imax) : Exception("")
{ {
std::stringstream str; 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()); 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)) #define NG_EXCEPTION(s) ngcore::Exception(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t"+std::string(s))
#ifdef NETGEN_ENABLE_CHECK_RANGE #ifdef NETGEN_ENABLE_CHECK_RANGE
#define NETGEN_CHECK_RANGE(value, min, max) \ #define NETGEN_CHECK_RANGE(value, min, max_plus_one) \
{ if ((value)<(min) || (value)>=(max)) \ { if ((value)<(min) || (value)>=(max_plus_one)) \
throw ngcore::RangeException(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", (value), (min), (max)); } throw ngcore::RangeException(__FILE__ ":" NETGEN_CORE_NGEXEPTION_STR(__LINE__) "\t", (value), (min), (max_plus_one)); }
#else // NETGEN_ENABLE_CHECK_RANGE #else // NETGEN_ENABLE_CHECK_RANGE
#define NETGEN_CHECK_RANGE(value, min, max) #define NETGEN_CHECK_RANGE(value, min, max)
#endif // NETGEN_ENABLE_CHECK_RANGE #endif // NETGEN_ENABLE_CHECK_RANGE

37
tests/catch/array.cpp Normal file
View File

@ -0,0 +1,37 @@
#include "catch.hpp"
#include <array.hpp>
using namespace ngcore;
using namespace std;
TEST_CASE("Array")
{
Array<int> array;
#ifdef DEBUG
CHECK_THROWS_AS(array[0], RangeException);
CHECK_THROWS_AS(array.DeleteLast(), RangeException);
CHECK_THROWS_AS(array.Last(), RangeException);
#endif // DEBUG
Array<double> 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<double>));
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<int>(4);
b = 2;
int count = 0;
for(auto val : b)
{
count++;
CHECK(val == 2);
}
CHECK(count == 4);
}