12 #ifndef ECL_CONTAINERS_ARRAY_MEM_CHECK_HPP_
13 #define ECL_CONTAINERS_ARRAY_MEM_CHECK_HPP_
14 #ifdef ECL_MEM_CHECK_ARRAYS
23 #include "../definitions.hpp"
24 #include "../initialiser.hpp"
25 #include "../stencil.hpp"
43 namespace blueprints {
45 template <
typename Type,
size_t N>
class ArrayFactory;
46 template <
typename Derived>
class ArrayBluePrint;
47 template <
typename Type,
size_t Size>
class ConstantArray;
51 namespace formatters {
53 template <
typename Type,
size_t N>
class ArrayFormatter;
105 template<
typename Type, std::
size_t Size = DynamicStorage>
106 class ECL_PUBLIC Array :
public blueprints::ArrayFactory<Type,Size> {
111 typedef Type value_type;
112 typedef Type* iterator;
113 typedef const Type* const_iterator;
114 typedef Type& reference;
115 typedef const Type& const_reference;
116 typedef std::size_t size_type;
117 typedef std::ptrdiff_t difference_type;
118 typedef std::reverse_iterator<iterator> reverse_iterator;
119 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
120 typedef blueprints::ArrayFactory<value_type,Size> Factory;
121 typedef formatters::ArrayFormatter<Type,Size> Formatter;
130 Array() { initialiseMagicSections(); };
154 Array(
const blueprints::ArrayBluePrint< T > &blueprint) {
156 blueprint.implementApply(*
this);
157 initialiseMagicSections();
178 containers::BoundedListInitialiser<Type,Type*,Size>
operator<<(
const Type &value) {
179 return containers::BoundedListInitialiser<value_type,iterator,Size>(value,elements);
189 iterator begin() {
return elements; }
194 const_iterator begin()
const {
return elements; }
199 iterator end() {
return elements+Size; }
204 const_iterator end()
const {
return elements+Size; }
209 reverse_iterator rbegin() {
return reverse_iterator(end()); }
214 const_reverse_iterator rbegin()
const {
return const_reverse_iterator(end()); }
219 reverse_iterator rend() {
return reverse_iterator(begin()); }
224 const_reverse_iterator rend()
const {
return const_reverse_iterator(begin()); }
233 reference front() {
return elements[0]; }
238 const_reference front()
const {
return elements[0]; }
243 reference back() {
return elements[Size-1]; }
248 const_reference back()
const {
return elements[Size-1]; }
264 Stencil< Array<Type,Size> > stencil(
const unsigned int& start_index,
const unsigned int& n) {
267 return Stencil< Array<Type,Size> >(*
this, begin()+start_index, begin()+start_index+n);
278 reference operator[](size_type i) {
293 const_reference operator[](size_type i)
const {
307 reference at(size_type i) {
325 const_reference at(size_type i)
const {
340 static size_type size() {
return Size; }
352 template <
typename OutputStream,
typename ElementType,
size_t ArraySize>
353 friend OutputStream&
operator<<(OutputStream &ostream ,
const Array<ElementType,ArraySize> &array);
358 bool bufferUnderRun();
359 bool bufferOverRun();
360 bool bufferOverFlow();
363 void initialiseMagicSections();
365 static const unsigned int& bufferOverrunLength() {
366 static const unsigned int buffer_overrun_length = 4;
367 return buffer_overrun_length;
369 static const unsigned int& bufferUnderrunLength() {
370 static const unsigned int buffer_underrun_length = 4;
371 return buffer_underrun_length;
373 static const char& magicChar() {
374 static const char magic_char = 0xCC;
378 value_type elements[Size];
391 template<
typename Type,
size_t Size>
392 void Array<Type,Size>::initialiseMagicSections() {
394 for (
unsigned int i = 0; i < bufferUnderrunLength(); ++i ) {
395 underrun[i] = magicChar();
397 for (
unsigned int i = 0; i < bufferOverrunLength(); ++i ) {
398 overrun[i] = magicChar();
411 template<
typename Type,
size_t Size>
412 bool Array<Type,Size>::bufferOverRun() {
414 for (
unsigned int i = 0; i < bufferOverrunLength(); ++i ) {
415 if ( overrun[i] != magicChar() ) {
430 template<
typename Type,
size_t Size>
431 bool Array<Type,Size>::bufferUnderRun() {
432 for (
unsigned int i = 0; i < bufferUnderrunLength(); ++i ) {
433 if ( underrun[i] != magicChar() ) {
448 template<
typename Type,
size_t Size>
449 bool Array<Type,Size>::bufferOverFlow() {
450 return ( bufferOverRun() || bufferUnderRun() );
458 template <
typename OutputStream,
typename ElementType,
size_t ArraySize>
459 OutputStream&
operator<<(OutputStream &ostream ,
const Array<ElementType,ArraySize> &array) {
464 for(
size_t i = 0; i < ArraySize; ++i )
466 ostream << array[i] <<
" ";
478 namespace blueprints {
504 template <
typename Derived>
505 class ArrayBluePrint {
519 template <
typename BaseType>
521 return static_cast<Derived*
>(
this)->instantiate();
536 template <
typename BaseType>
538 static_cast<const Derived*
>(
this)->apply(array);
551 template <
typename Type,
size_t Size>
552 class ConstantArray :
public ArrayBluePrint< ConstantArray<Type, Size> > {
582 std::fill_n(array.
begin(),Size,
val);
591 std::fill_n(array.begin(),Size,
val);
606 template<
typename Type,
size_t Size>
615 static ConstantArray<Type,Size>
Constant(
const Type& value) {
616 return ConstantArray<Type,Size>(value);