$search
00001 00008 /***************************************************************************** 00009 ** Ifdefs 00010 *****************************************************************************/ 00011 00012 #ifndef ECL_CONTAINERS_ARRAY_DYNAMIC_NO_MEM_CHECK_HPP_ 00013 #define ECL_CONTAINERS_ARRAY_DYNAMIC_NO_MEM_CHECK_HPP_ 00014 00015 /***************************************************************************** 00016 ** Includes 00017 *****************************************************************************/ 00018 00019 #include <algorithm> 00020 #include <ecl/config/macros.hpp> 00021 #include <ecl/utilities/blueprints.hpp> 00022 #include "../definitions.hpp" 00023 #include "../initialiser.hpp" 00024 #include "../stencil.hpp" 00025 #include "array_no_mem_check.hpp" 00026 00027 /***************************************************************************** 00028 ** Namespaces 00029 *****************************************************************************/ 00030 00031 namespace ecl { 00032 00033 /***************************************************************************** 00034 ** Forward Declarations 00035 *****************************************************************************/ 00036 00037 template <typename Type> class Array<Type,DynamicStorage>; 00038 00039 namespace blueprints { 00040 00041 template <typename Type> class ConstantDynamicArray; 00042 00043 } // namespace blueprints 00044 00045 namespace formatters { 00046 00047 template <typename Type, size_t N> class ArrayFormatter; 00048 00049 } // namespace formatters 00050 00051 /***************************************************************************** 00052 ** BluePrintFactory 00053 *****************************************************************************/ 00062 template<typename Type> 00063 class ECL_PUBLIC BluePrintFactory< Array<Type,DynamicStorage> > { 00064 public: 00073 static blueprints::ConstantDynamicArray<Type> Constant(size_t size, const Type &value) { 00074 return blueprints::ConstantDynamicArray<Type>(size,value); 00075 } 00076 virtual ~BluePrintFactory() {}; 00077 }; 00078 00079 /***************************************************************************** 00080 ** Interface [Array][Dynamic] 00081 *****************************************************************************/ 00128 template<typename Type> 00129 class ECL_PUBLIC Array<Type,DynamicStorage> : public BluePrintFactory< Array<Type,DynamicStorage> > { 00130 public: 00131 /********************* 00132 ** Typedefs 00133 **********************/ 00134 typedef Type value_type; 00135 typedef Type* iterator; 00136 typedef const Type* const_iterator; 00137 typedef Type& reference; 00138 typedef const Type& const_reference; 00139 typedef std::size_t size_type; 00140 typedef std::ptrdiff_t difference_type; 00141 typedef std::reverse_iterator<iterator> reverse_iterator; 00142 typedef std::reverse_iterator<const_iterator> const_reverse_iterator; 00143 typedef formatters::ArrayFormatter<Type,DynamicStorage> Formatter; 00146 typedef BluePrintFactory< Array<Type,DynamicStorage> > Factory; 00147 00148 /********************* 00149 ** Constructors 00150 **********************/ 00156 explicit Array() : buffer_size(0), buffer(NULL) {} 00165 explicit Array(const unsigned int reserve_size) : buffer_size(reserve_size), buffer(NULL) { 00166 buffer = new Type[reserve_size]; 00167 }; 00175 Array(const Array<Type,DynamicStorage>& array) : 00176 Factory(), 00177 buffer_size(0), 00178 buffer(NULL) 00179 { 00180 if ( array.size() != 0 ) { 00181 resize(array.size()); 00182 std::copy(array.begin(),array.end(),begin()); 00183 } 00184 } 00205 template<typename T> 00206 Array(const blueprints::ArrayBluePrint< T > &blueprint) : buffer_size(0), buffer(NULL) { 00207 // Note we're using a partially specialised parent interface here otherwise the 00208 // constructor that reserves sizes as well as the comma initialiser won't 00209 // conveniently convert types correctly 00210 // (e.g. Array<double> array(4); array = 1,2,3,4; will fail) 00211 ecl_compile_time_concept_check(BluePrintConcept<T>); 00212 blueprint.implementApply(*this); 00213 } 00219 ~Array() { 00220 if ( buffer != NULL ) { 00221 delete[] buffer; 00222 } 00223 } 00224 /********************* 00225 ** Assignment 00226 **********************/ 00240 containers::BoundedListInitialiser<value_type,iterator,DynamicStorage> operator<<(const Type &value) { 00241 return containers::BoundedListInitialiser<value_type,iterator,DynamicStorage>(value,buffer,buffer_size); 00242 } 00243 00244 void operator=(const Array<Type,DynamicStorage>& array) { 00245 if ( array.size() == 0 ) { 00246 clear(); 00247 } else { 00248 resize(array.size()); 00249 std::copy(array.begin(),array.end(),begin()); 00250 } 00251 } 00252 00253 /********************* 00254 ** Iterators 00255 **********************/ 00262 iterator begin() ecl_assert_throw_decl(StandardException) { 00263 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00264 return buffer; 00265 } 00272 const_iterator begin() const ecl_assert_throw_decl(StandardException) { 00273 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00274 return buffer; 00275 } 00282 iterator end() ecl_assert_throw_decl(StandardException) { 00283 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00284 return buffer+buffer_size; 00285 } 00292 const_iterator end() const ecl_assert_throw_decl(StandardException) { 00293 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00294 return buffer+buffer_size; 00295 } 00302 reverse_iterator rbegin() ecl_assert_throw_decl(StandardException) { 00303 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00304 return reverse_iterator(end()); 00305 } 00312 const_reverse_iterator rbegin() const ecl_assert_throw_decl(StandardException) { 00313 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00314 return const_reverse_iterator(end()); 00315 } 00322 reverse_iterator rend() ecl_assert_throw_decl(StandardException) { 00323 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00324 return reverse_iterator(begin()); 00325 } 00332 const_reverse_iterator rend() const ecl_assert_throw_decl(StandardException) { 00333 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00334 return const_reverse_iterator(begin()); 00335 } 00336 00337 /********************* 00338 ** Front/Back 00339 **********************/ 00346 reference front() ecl_assert_throw_decl(StandardException) { 00347 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00348 return buffer[0]; 00349 } 00356 const_reference front() const ecl_assert_throw_decl(StandardException) { 00357 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00358 return buffer[0]; 00359 } 00366 reference back() ecl_assert_throw_decl(StandardException) { 00367 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00368 return buffer[buffer_size-1]; 00369 } 00376 const_reference back() const ecl_assert_throw_decl(StandardException) { 00377 ecl_assert_throw( buffer != NULL, StandardException(LOC,OutOfRangeError) ); 00378 return buffer[buffer_size-1]; 00379 } 00380 00381 /********************* 00382 ** Accessors 00383 **********************/ 00395 Stencil< Array<Type,DynamicStorage> > stencil(const unsigned int& start_index, const unsigned int& n) ecl_assert_throw_decl(StandardException) { 00396 ecl_assert_throw(start_index < size(), StandardException(LOC, OutOfRangeError, "Start index provided is larger than the underlying array size.")); 00397 ecl_assert_throw(start_index+n <= size(), StandardException(LOC, OutOfRangeError, "Finish index provided is larger than the underlying array size.")); 00398 return Stencil< Array<Type,DynamicStorage> >(*this, begin()+start_index, begin()+start_index+n); 00399 } 00409 reference operator[](size_type i) ecl_assert_throw_decl(StandardException) { 00410 ecl_assert_throw( i<buffer_size, StandardException(LOC,OutOfRangeError)); 00411 return buffer[i]; 00412 } 00424 const_reference operator[](size_type i) const ecl_assert_throw_decl(StandardException) { 00425 ecl_assert_throw( i<buffer_size, StandardException(LOC,OutOfRangeError)); 00426 return buffer[i]; 00427 } 00438 reference at(size_type i) throw(StandardException) { 00439 if ( i>=buffer_size ) { 00440 throw StandardException(LOC,OutOfRangeError); 00441 } 00442 return buffer[i]; 00443 } 00456 const_reference at(size_type i) const throw(StandardException) { 00457 if ( i>=buffer_size ) { 00458 throw StandardException(LOC,OutOfRangeError); 00459 } 00460 return buffer[i]; 00461 } 00462 00463 /********************* 00464 ** Utilities 00465 **********************/ 00473 size_type size() const { return buffer_size; } 00474 00483 void resize( size_t n ) { 00484 if ( buffer != NULL ) { 00485 delete[] buffer; 00486 } 00487 buffer = new Type[n]; 00488 buffer_size = n; 00489 } 00495 void clear() { 00496 if ( buffer != NULL ) { 00497 delete[] buffer; 00498 buffer = NULL; 00499 } 00500 buffer_size = 0; 00501 } 00502 00503 /********************* 00504 ** Streaming 00505 **********************/ 00513 template <typename OutputStream, typename ElementType> 00514 friend OutputStream& operator<<(OutputStream &ostream , const Array<ElementType,DynamicStorage> &array); 00515 00516 private: 00517 unsigned int buffer_size; 00518 Type *buffer; 00519 00520 }; 00521 00522 /***************************************************************************** 00523 ** Implementation [Array] 00524 *****************************************************************************/ 00525 00526 template <typename OutputStream, typename ElementType> 00527 OutputStream& operator<<(OutputStream &ostream , const Array<ElementType,DynamicStorage> &array) { 00528 00529 ostream << "[ "; 00530 for(size_t i = 0; i < array.buffer_size; ++i ) 00531 { 00532 ostream << array[i] << " "; 00533 } 00534 ostream << "]"; 00535 ostream.flush(); 00536 00537 return ostream; 00538 } 00539 00540 /***************************************************************************** 00541 ** BluePrints 00542 *****************************************************************************/ 00543 00544 namespace blueprints { 00545 00546 /***************************************************************************** 00547 ** Interface [ConstantDynamicArray] 00548 *****************************************************************************/ 00549 00557 template <typename Type> 00558 class ConstantDynamicArray: public ArrayBluePrint< ConstantDynamicArray<Type> > { 00559 public: 00563 typedef ecl::Array<Type,ecl::DynamicStorage> base_type; 00569 ConstantDynamicArray() {}; 00570 00580 ConstantDynamicArray(size_t size, const Type &value ) : 00581 reserve_size(size), 00582 val(value) 00583 {} 00584 00585 virtual ~ConstantDynamicArray() {}; 00586 00597 base_type instantiate() { 00598 ecl::Array<Type> array(reserve_size); 00599 std::fill_n(array.begin(),reserve_size,val); 00600 return array; 00601 } 00602 00611 void apply(base_type& array) const { 00612 array.resize(reserve_size); 00613 std::fill_n(array.begin(),reserve_size,val); 00614 } 00615 00616 private: 00617 size_t reserve_size; 00618 Type val; 00619 }; 00620 00621 00622 } // namespace blueprints 00623 } // namespace ecl 00624 00625 00626 #endif /* ECL_CONTAINERS_ARRAY_DYNAMIC_NO_MEM_CHECK_HPP_ */