00001
00008
00009
00010
00011
00012 #ifndef ECL_CONTAINERS_ARRAY_NO_MEM_CHECK_HPP_
00013 #define ECL_CONTAINERS_ARRAY_NO_MEM_CHECK_HPP_
00014 #ifndef ECL_MEM_CHECK_ARRAYS
00015
00016
00017
00018
00019
00020 #include <algorithm>
00021 #include <cstddef>
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
00035
00036
00037 namespace ecl {
00038
00039
00040
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 }
00050
00051 namespace formatters {
00052
00053 template <typename Type, size_t N> class ArrayFormatter;
00054
00055 }
00056
00057
00058
00059
00105 template<typename Type, std::size_t Size = DynamicStorage>
00106 class ECL_PUBLIC Array : public blueprints::ArrayFactory<Type,Size> {
00107 public:
00108
00109
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
00125
00130 Array() {};
00153 template<typename T>
00154 Array(const blueprints::ArrayBluePrint< T > &blueprint) {
00155 ecl_compile_time_concept_check(BluePrintConcept<T>);
00156 blueprint.implementApply(*this);
00157 }
00158
00159 virtual ~Array() {};
00160
00161
00162
00163
00177 containers::BoundedListInitialiser<Type,Type*,Size> operator<<(const Type &value) {
00178 return containers::BoundedListInitialiser<value_type,iterator,Size>(value,elements);
00179 }
00180
00181
00182
00183
00188 iterator begin() { return elements; }
00193 const_iterator begin() const { return elements; }
00198 iterator end() { return elements+Size; }
00203 const_iterator end() const { return elements+Size; }
00208 reverse_iterator rbegin() { return reverse_iterator(end()); }
00213 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
00218 reverse_iterator rend() { return reverse_iterator(begin()); }
00223 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
00224
00225
00226
00227
00232 reference front() { return elements[0]; }
00237 const_reference front() const { return elements[0]; }
00242 reference back() { return elements[Size-1]; }
00247 const_reference back() const { return elements[Size-1]; }
00248
00249
00250
00251
00263 Stencil< Array<Type,Size> > stencil(const unsigned int& start_index, const unsigned int& n) ecl_assert_throw_decl(StandardException) {
00264 ecl_assert_throw(start_index < Size, StandardException(LOC, OutOfRangeError, "Start index provided is larger than the underlying array size."));
00265 ecl_assert_throw(start_index+n <= Size, StandardException(LOC, OutOfRangeError, "Finish index provided is larger than the underlying array size."));
00266 return Stencil< Array<Type,Size> >(*this, begin()+start_index, begin()+start_index+n);
00267 }
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
00334
00340 static size_type size() { return Size; }
00341
00342
00343
00344
00352 template <typename OutputStream, typename ElementType, size_t ArraySize>
00353 friend OutputStream& operator<<(OutputStream &ostream , const Array<ElementType,ArraySize> &array);
00354
00355 private:
00356 value_type elements[Size];
00357 };
00358
00359
00360
00361
00362
00363 template <typename OutputStream, typename ElementType, size_t ArraySize>
00364 OutputStream& operator<<(OutputStream &ostream , const Array<ElementType,ArraySize> &array) {
00365
00366 ecl_compile_time_concept_check(StreamConcept<OutputStream>);
00367
00368 ostream << "[ ";
00369 for(size_t i = 0; i < ArraySize; ++i )
00370 {
00371 ostream << array[i] << " ";
00372 }
00373 ostream << "]";
00374 ostream.flush();
00375
00376 return ostream;
00377 }
00378
00379
00380
00381
00382
00383
00384 namespace blueprints {
00385
00410 template <typename Derived>
00411 class ArrayBluePrint {
00412 public:
00425 template <typename BaseType>
00426 BaseType implementInstantiate() {
00427 return static_cast<Derived*>(this)->instantiate();
00428 }
00442 template <typename BaseType>
00443 void implementApply(BaseType& array) const {
00444 static_cast<const Derived*>(this)->apply(array);
00445 }
00446
00447 virtual ~ArrayBluePrint() {}
00448 };
00457 template <typename Type, size_t Size>
00458 class ConstantArray : public ArrayBluePrint< ConstantArray<Type, Size> > {
00459 public:
00463 typedef ecl::Array<Type,Size> base_type;
00472 ConstantArray(const Type& value = 0) : val(value) {}
00473
00474 virtual ~ConstantArray() {};
00475
00486 base_type instantiate() {
00487 ecl::Array<Type,Size> array;
00488 std::fill_n(array.begin(),Size,val);
00489 return array;
00490 }
00491
00496 void apply(base_type& array) const {
00497 std::fill_n(array.begin(),Size,val);
00498 }
00499
00500 private:
00501 const Type& val;
00502 };
00503
00512 template<typename Type, size_t Size>
00513 class ArrayFactory {
00514 public:
00521 static ConstantArray<Type,Size> Constant(const Type& value) {
00522 return ConstantArray<Type,Size>(value);
00523 }
00524
00525 virtual ~ArrayFactory() {};
00526 };
00527
00528 }
00529 }
00530
00531 #endif
00532 #endif