array_mem_check.hpp
Go to the documentation of this file.
00001 
00008 /*****************************************************************************
00009 ** Ifdefs
00010 *****************************************************************************/
00011 
00012 #ifndef ECL_CONTAINERS_ARRAY_MEM_CHECK_HPP_
00013 #define ECL_CONTAINERS_ARRAY_MEM_CHECK_HPP_
00014 #ifdef ECL_MEM_CHECK_ARRAYS
00015 
00016 /*****************************************************************************
00017 ** Includes
00018 *****************************************************************************/
00019 
00020 #include <algorithm> // std::copy
00021 #include <cstddef>  // size_t
00022 #include <iterator>
00023 #include "../definitions.hpp"
00024 #include "../initialiser.hpp"
00025 #include "../stencil.hpp"
00026 #include <ecl/config/macros.hpp>
00027 #include <ecl/concepts/macros.hpp>
00028 #include <ecl/concepts/blueprints.hpp>
00029 #include <ecl/concepts/streams.hpp>
00030 #include <ecl/errors/compile_time_assert.hpp>
00031 #include <ecl/exceptions/standard_exception.hpp>
00032 
00033 /*****************************************************************************
00034 ** Namespaces
00035 *****************************************************************************/
00036 
00037 namespace ecl {
00038 
00039 /*****************************************************************************
00040 ** Forward Declarations
00041 *****************************************************************************/
00042 
00043 namespace blueprints {
00044 
00045 template <typename Type, size_t N> class ArrayFactory;
00046 template <typename Derived> class ArrayBluePrint;
00047 template <typename Type, size_t Size> class ConstantArray;
00048 
00049 } // namespace blueprints
00050 
00051 namespace formatters {
00052 
00053 template <typename Type, size_t N> class ArrayFormatter;
00054 
00055 } // namespace formatters
00056 
00057 /*****************************************************************************
00058 ** Interface [Array][Fixed]
00059 *****************************************************************************/
00105 template<typename Type, std::size_t Size = DynamicStorage>
00106 class ECL_PUBLIC Array : public blueprints::ArrayFactory<Type,Size> {
00107     public:
00108         /*********************
00109         ** Typedefs
00110         **********************/
00111         typedef Type           value_type; 
00112         typedef Type*          iterator;   
00113         typedef const Type*    const_iterator;  
00114         typedef Type&          reference;  
00115         typedef const Type&    const_reference; 
00116         typedef std::size_t    size_type;  
00117         typedef std::ptrdiff_t difference_type;
00118         typedef std::reverse_iterator<iterator> reverse_iterator; 
00119         typedef std::reverse_iterator<const_iterator> const_reverse_iterator;  
00120         typedef blueprints::ArrayFactory<value_type,Size> Factory; 
00121         typedef formatters::ArrayFormatter<Type,Size> Formatter; 
00123         /*********************
00124         ** Constructors
00125         **********************/
00130         Array() { initialiseMagicSections(); };
00153         template<typename T>
00154         Array(const blueprints::ArrayBluePrint< T > &blueprint) {
00155             ecl_compile_time_concept_check(BluePrintConcept<T>);
00156             blueprint.implementApply(*this);
00157             initialiseMagicSections();
00158         }
00159 
00160         virtual ~Array() {}; // The user should manually check these in the classes that hold them.
00161 
00162         /*********************
00163         ** Assignment
00164         **********************/
00178         containers::BoundedListInitialiser<Type,Type*,Size> operator<<(const Type &value) {
00179             return containers::BoundedListInitialiser<value_type,iterator,Size>(value,elements);
00180         }
00181 
00182         /*********************
00183         ** Iterators
00184         **********************/
00189         iterator begin() { return elements; }
00194         const_iterator begin() const { return elements; }
00199         iterator end() { return elements+Size; }
00204         const_iterator end() const { return elements+Size; }
00209         reverse_iterator rbegin() { return reverse_iterator(end()); }
00214         const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00219         reverse_iterator rend() { return reverse_iterator(begin()); }
00224         const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00225 
00226         /*********************
00227         ** Front/Back
00228         **********************/
00233         reference front() { return elements[0]; }
00238         const_reference front() const { return elements[0]; }
00243         reference back() { return elements[Size-1]; }
00248         const_reference back() const { return elements[Size-1]; }
00249 
00250         /*********************
00251         ** Accessors
00252         **********************/
00264         Stencil< Array<Type,Size> > stencil(const unsigned int& start_index, const unsigned int& n) ecl_assert_throw_decl(StandardException) {
00265                 ecl_assert_throw(start_index < Size, StandardException(LOC, OutOfRangeError, "Start index provided is larger than the underlying array size."));
00266                 ecl_assert_throw(start_index+n <= Size, StandardException(LOC, OutOfRangeError, "Finish index provided is larger than the underlying array size."));
00267                 return Stencil< Array<Type,Size> >(*this, begin()+start_index, begin()+start_index+n);
00268         }
00278         reference operator[](size_type i) ecl_assert_throw_decl(StandardException) {
00279             ecl_assert_throw( i<Size, StandardException(LOC,OutOfRangeError));
00280             return elements[i];
00281         }
00293         const_reference operator[](size_type i) const ecl_assert_throw_decl(StandardException) {
00294             ecl_assert_throw( i<Size, StandardException(LOC,OutOfRangeError));
00295             return elements[i];
00296         }
00307         reference at(size_type i) throw(StandardException) {
00308             if ( i>=Size ) {
00309                 throw StandardException(LOC,OutOfRangeError);
00310             }
00311             return elements[i];
00312         }
00325         const_reference at(size_type i) const throw(StandardException) {
00326             if ( i>=Size ) {
00327                 throw StandardException(LOC,OutOfRangeError);
00328             }
00329             return elements[i];
00330         }
00331 
00332         /*********************
00333         ** Utilities
00334         **********************/
00340         static size_type size() { return Size; }
00341 
00342         /*********************
00343         ** Streaming
00344         **********************/
00352         template <typename OutputStream, typename ElementType, size_t ArraySize>
00353         friend OutputStream& operator<<(OutputStream &ostream , const Array<ElementType,ArraySize> &array);
00354 
00355         /******************************************
00356                 ** Buffer under/overrun checks
00357                 *******************************************/
00358         bool bufferUnderRun();
00359         bool bufferOverRun();
00360         bool bufferOverFlow();
00361 
00362     private:
00363         void initialiseMagicSections();
00364 
00365         static const unsigned int& bufferOverrunLength() {
00366             static const unsigned int buffer_overrun_length = 4;
00367             return buffer_overrun_length;
00368         }
00369         static const unsigned int& bufferUnderrunLength() {
00370             static const unsigned int buffer_underrun_length = 4;
00371             return buffer_underrun_length;
00372         }
00373         static const char& magicChar() {
00374             static const char magic_char = 0xCC;
00375             return magic_char;
00376         }
00377         char underrun[4];
00378         value_type elements[Size];
00379         char overrun[4];
00380 };
00381 
00382 /*****************************************************************************
00383 ** Implementation [Array]
00384 *****************************************************************************/
00391 template<typename Type, size_t Size>
00392 void Array<Type,Size>::initialiseMagicSections() {
00393 
00394         for ( unsigned int i = 0; i < bufferUnderrunLength(); ++i ) {
00395                 underrun[i] = magicChar();
00396         }
00397         for ( unsigned int i = 0; i < bufferOverrunLength(); ++i ) {
00398                 overrun[i] = magicChar();
00399         }
00400 
00401 }
00411 template<typename Type, size_t Size>
00412 bool Array<Type,Size>::bufferOverRun() {
00413 
00414         for ( unsigned int i = 0; i < bufferOverrunLength(); ++i ) {
00415                 if ( overrun[i] != magicChar() ) {
00416                         return true;
00417                 }
00418         }
00419         return false;
00420 }
00421 
00430 template<typename Type, size_t Size>
00431 bool Array<Type,Size>::bufferUnderRun() {
00432         for ( unsigned int i = 0; i < bufferUnderrunLength(); ++i ) {
00433                 if ( underrun[i] != magicChar() ) {
00434                         return true;
00435                 }
00436         }
00437         return false;
00438 }
00448 template<typename Type, size_t Size>
00449 bool Array<Type,Size>::bufferOverFlow() {
00450         return ( bufferOverRun() || bufferUnderRun() );
00451 }
00452 
00453 
00454 /*****************************************************************************
00455 ** Implementation [Array][Streaming]
00456 *****************************************************************************/
00457 
00458 template <typename OutputStream, typename ElementType, size_t ArraySize>
00459 OutputStream& operator<<(OutputStream &ostream , const Array<ElementType,ArraySize> &array) {
00460 
00461         ecl_compile_time_concept_check(StreamConcept<OutputStream>);
00462 
00463     ostream << "[ ";
00464     for(size_t i = 0; i < ArraySize; ++i )
00465     {
00466         ostream << array[i] << " ";
00467     }
00468     ostream << "]";
00469     ostream.flush();
00470 
00471     return ostream;
00472 }
00473 
00474 /*****************************************************************************
00475 ** BluePrints
00476 *****************************************************************************/
00477 
00478 namespace blueprints {
00479 
00504 template <typename Derived>
00505 class ArrayBluePrint {
00506     public:
00519         template <typename BaseType>
00520         BaseType implementInstantiate() {
00521             return static_cast<Derived*>(this)->instantiate();
00522         }
00536         template <typename BaseType>
00537         void implementApply(BaseType& array) const {
00538             static_cast<const Derived*>(this)->apply(array);
00539         }
00540 
00541         virtual ~ArrayBluePrint() {}
00542 };
00551 template <typename Type, size_t Size>
00552 class ConstantArray : public ArrayBluePrint< ConstantArray<Type, Size> > {
00553     public:
00557         typedef ecl::Array<Type,Size> base_type;
00566         ConstantArray(const Type& value = 0) : val(value) {}
00567 
00568         virtual ~ConstantArray() {};
00569 
00580         base_type instantiate() {
00581             ecl::Array<Type,Size> array;
00582             std::fill_n(array.begin(),Size,val);
00583             return array;
00584         }
00585 
00590         void apply(base_type& array) const {
00591             std::fill_n(array.begin(),Size,val);
00592         }
00593 
00594     private:
00595         const Type& val;
00596 };
00597 
00606 template<typename Type, size_t Size>
00607 class ArrayFactory {
00608     public:
00615         static ConstantArray<Type,Size> Constant(const Type& value) {
00616             return ConstantArray<Type,Size>(value);
00617         }
00618 
00619         virtual ~ArrayFactory() {};
00620 };
00621 
00622 } // namespace blueprints
00623 } // namespace ecl
00624 
00625 #endif /* ECL_MEM_CHECK_ARRAYS */
00626 #endif /* ECL_CONTAINERS_ARRAY_MEM_CHECK_HPP_ */


ecl_containers
Author(s): Daniel Stonier (d.stonier@gmail.com)
autogenerated on Thu Jan 2 2014 11:12:25