Created by Scott Robert Ladd at Coyote Gulch Productions.
00001 //--------------------------------------------------------------------- 00002 // Algorithmic Conjurings @ http://www.coyotegulch.com 00003 // 00004 // array.h (libcoyotl) 00005 // 00006 // Templatized array classes compatible with STL containers and 00007 // algorithms. 00008 //--------------------------------------------------------------------- 00009 // 00010 // Copyright 1990-2005 Scott Robert Ladd 00011 // 00012 // This program is free software; you can redistribute it and/or modify 00013 // it under the terms of the GNU General Public License as published by 00014 // the Free Software Foundation; either version 2 of the License, or 00015 // (at your option) any later version. 00016 // 00017 // This program is distributed in the hope that it will be useful, 00018 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of the GNU General Public License 00023 // along with this program; if not, write to the 00024 // Free Software Foundation, Inc. 00025 // 59 Temple Place - Suite 330 00026 // Boston, MA 02111-1307, USA. 00027 // 00028 //----------------------------------------------------------------------- 00029 // 00030 // For more information on this software package, please visit 00031 // Scott's web site, Coyote Gulch Productions, at: 00032 // 00033 // http://www.coyotegulch.com 00034 // 00035 //----------------------------------------------------------------------- 00036 00037 #if !defined(LIBCOYOTL_ARRAY_H) 00038 #define LIBCOYOTL_ARRAY_H 00039 00040 // Microsoft Visual C++-specific pragmas 00041 #if defined(_MSC_VER) 00042 #pragma warning(disable : 4290 4101) // "exception specification ignored", "unused var" 00043 #endif 00044 00045 #include <cstddef> // for size_t 00046 #include <algorithm> // for lexicographical_compare 00047 00048 #include "validator.h" // validation functions 00049 #include "realutil.h" // need min_of function 00050 00051 #if defined(LIBCOYOTL_BOUNDS_CHECKING) 00052 #include <stdexcept> 00053 #include <sstream> 00054 #define LIBCOYOTL_ARRAY_EXCEPTIONS validation_error<size_t> 00055 #define LIBCOYOTL_ARRAY_CHECK_INDEX(n) validate_less(n,m_size,LIBCOYOTL_LOCATION); 00056 #else 00057 #define LIBCOYOTL_ARRAY_EXCEPTIONS 00058 #define LIBCOYOTL_ARRAY_CHECK_INDEX(n) 00059 #endif 00060 00061 namespace libcoyotl 00062 { 00064 00071 template <typename Type> 00072 class array 00073 { 00074 public: 00076 typedef Type value_type; 00077 00079 typedef Type * pointer; 00080 00082 typedef const Type * const_pointer; 00083 00085 typedef Type & reference; 00086 00088 typedef const Type & const_reference; 00089 00091 typedef ptrdiff_t difference_type; 00092 00094 typedef size_t size_type; 00095 00097 typedef Type * iterator; 00098 00100 typedef const Type * const_iterator; 00101 00103 typedef Type * reverse_iterator; 00104 00106 typedef const Type * const_reverse_iterator; 00107 00109 00113 array(size_t a_length); 00114 00116 00122 array(size_t a_length, const Type & a_init_value); 00123 00125 00129 array(const array<Type> & a_source); 00130 00132 00138 array(size_t a_length, const Type * a_carray); 00139 00141 00148 virtual ~array() throw(); 00149 00151 00155 array & operator = (const array<Type> & a_source) throw(); 00156 00158 00163 array & operator = (const Type & a_value) throw(); 00164 00166 00171 array & operator = (const Type * a_carray) throw(); 00172 00174 00180 const Type * c_array() const throw(); 00181 00183 00188 Type & operator [] (size_t n) throw(LIBCOYOTL_ARRAY_EXCEPTIONS); 00189 00191 00196 Type operator [] (size_t n) const throw(LIBCOYOTL_ARRAY_EXCEPTIONS); 00197 00199 00204 void append(const array<Type> & a_array); 00205 00207 00211 iterator begin() throw(); 00212 00214 00218 const_iterator begin() const throw(); 00219 00221 00225 iterator end() throw(); 00226 00228 00232 const_iterator end() const throw(); 00233 00235 00239 iterator rbegin() throw(); 00240 00242 00246 const_iterator rbegin() const throw(); 00247 00249 00253 iterator rend() throw(); 00254 00256 00260 const_iterator rend() const throw(); 00261 00263 00269 bool operator == (const array<Type> & a_comparand) const throw(); 00270 00272 00278 bool operator != (const array<Type> & a_comparand) const throw(); 00279 00281 00287 bool operator < (const array<Type> & a_comparand) const throw(); 00288 00290 00296 bool operator <= (const array<Type> & a_comparand) const throw(); 00297 00299 00305 bool operator > (const array<Type> & a_comparand) const throw(); 00306 00308 00314 bool operator >= (const array<Type> & a_comparand) const throw(); 00315 00317 00322 void swap(array<Type> & a_source) throw(); 00323 00325 00330 size_t size() const throw(); 00331 00333 00338 size_t max_size() const throw(); 00339 00341 00346 bool empty() const throw(); 00347 00348 protected: 00350 Type * m_array; 00351 00353 size_t m_size; 00354 00355 private: 00356 // assign a single a_value to all elements 00357 void assign_value(const Type & a_value) throw(); 00358 00359 // copy elements from a c-style array 00360 void copy_carray(const Type * a_carray) throw(); 00361 00362 // copy elements from another array 00363 void copy_array(const array<Type> & a_source) throw(); 00364 }; 00365 00366 // assign a single a_value to all elements 00367 template <typename Type> 00368 void array<Type>::assign_value(const Type & a_value) throw() 00369 { 00370 Type * element_ptr = m_array; 00371 00372 for (size_t n = 0; n < m_size; ++n) 00373 { 00374 *element_ptr = a_value; 00375 ++element_ptr; 00376 } 00377 } 00378 00379 // copy elements from a c-style array 00380 template <typename Type> 00381 void array<Type>::copy_carray(const Type * a_carray) throw() 00382 { 00383 // use pointers for speed 00384 Type * target_ptr = m_array; 00385 const Type * carray_ptr = a_carray; 00386 00387 for (size_t n = 0; n < m_size; ++n) 00388 { 00389 *target_ptr = *carray_ptr; 00390 ++target_ptr; 00391 ++carray_ptr; 00392 } 00393 } 00394 00395 // copy elements from another array 00396 template <typename Type> 00397 void array<Type>::copy_array(const array<Type> & a_source) throw() 00398 { 00399 // find minimum a_length between the two arrays 00400 size_t copy_length = min_of(m_size,a_source.m_size); 00401 00402 // use pointers for speed 00403 Type * target_ptr = m_array; 00404 const Type * source_ptr = a_source.m_array; 00405 00406 for (size_t n = 0; n < copy_length; ++n) 00407 { 00408 *target_ptr = *source_ptr; 00409 ++target_ptr; 00410 ++source_ptr; 00411 } 00412 } 00413 00414 // default constructor 00415 template <typename Type> 00416 array<Type>::array(size_t a_length) 00417 : m_array(NULL), 00418 m_size(a_length) 00419 { 00420 // enforce lower limit on a_length 00421 enforce_lower_limit(m_size,size_t(1)); 00422 00423 // allocate array 00424 m_array = new Type [m_size]; 00425 } 00426 00427 // a_value constructor 00428 template <typename Type> 00429 array<Type>::array(size_t a_length, const Type & a_init_value) 00430 : m_array(NULL), 00431 m_size(a_length) 00432 { 00433 // enforce lower limit on a_length 00434 enforce_lower_limit(m_size,size_t(1)); 00435 00436 // allocate array 00437 m_array = new Type [m_size]; 00438 00439 // assign values 00440 assign_value(a_init_value); 00441 } 00442 00443 // copy constructor 00444 template <typename Type> 00445 array<Type>::array(const array<Type> & a_source) 00446 : m_array(NULL), 00447 m_size(a_source.m_size) 00448 { 00449 // allocate array 00450 m_array = new Type [m_size]; 00451 00452 // copy a_source array 00453 copy_array(a_source); 00454 } 00455 00456 // construct from C-style array 00457 template <typename Type> 00458 array<Type>::array(size_t a_length, const Type * a_carray) 00459 : m_array(NULL), 00460 m_size(a_length) 00461 { 00462 // validate a_source 00463 validate_not(a_carray,(const Type *)NULL,LIBCOYOTL_LOCATION); 00464 00465 // enforce lower limit on a_length 00466 enforce_lower_limit(m_size,size_t(1)); 00467 00468 // allocate array 00469 m_array = new Type [m_size]; 00470 00471 // copy elements of c array 00472 copy_carray(a_carray); 00473 } 00474 00475 // destructor 00476 template <typename Type> 00477 array<Type>::~array() throw() 00478 { 00479 // clean up resources 00480 delete [] m_array; 00481 m_array = NULL; 00482 m_size = 0; 00483 } 00484 00485 // assignment operator 00486 template <typename Type> 00487 array<Type> & array<Type>::operator = (const array<Type> & a_source) throw() 00488 { 00489 copy_array(a_source); 00490 return *this; 00491 } 00492 00493 // assign all operator 00494 template <typename Type> 00495 array<Type> & array<Type>::operator = (const Type & a_value) throw() 00496 { 00497 assign_value(a_value); 00498 return *this; 00499 } 00500 00501 // assign from C-style array 00502 template <typename Type> 00503 array<Type> & array<Type>::operator = (const Type * a_source) throw() 00504 { 00505 copy_carray(a_source); 00506 return *this; 00507 } 00508 00509 // conversion to C-style array 00510 template <typename Type> 00511 inline const Type * array<Type>::c_array() const throw() 00512 { 00513 return m_array; 00514 } 00515 00516 // element access 00517 template <typename Type> 00518 inline Type & array<Type>::operator [] (size_t n) throw(LIBCOYOTL_ARRAY_EXCEPTIONS) 00519 { 00520 LIBCOYOTL_ARRAY_CHECK_INDEX(n) 00521 return m_array[n]; 00522 } 00523 00524 template <typename Type> 00525 inline Type array<Type>::operator [] (size_t n) const throw(LIBCOYOTL_ARRAY_EXCEPTIONS) 00526 { 00527 LIBCOYOTL_ARRAY_CHECK_INDEX(n) 00528 return m_array[n]; 00529 } 00530 00531 // appending 00532 template <typename Type> 00533 void array<Type>::append(const array<Type> & other) 00534 { 00535 size_t new_size = m_size + other.m_size; 00536 Type * new_array = new Type[new_size]; 00537 00538 Type * target = new_array; 00539 Type * a_source = m_array; 00540 size_t n; 00541 00542 // copy from this array 00543 for (n = 0; n < m_size; ++n) 00544 { 00545 *target = *a_source; 00546 ++target; 00547 ++a_source; 00548 } 00549 00550 // copy from other array 00551 a_source = other.m_array; 00552 00553 for (n = 0; n < other.m_size; ++n) 00554 { 00555 *target = *a_source; 00556 ++target; 00557 ++a_source; 00558 } 00559 00560 // set this to use new array, destroying old one 00561 m_size = new_size; 00562 delete [] m_array; 00563 m_array = new_array; 00564 } 00565 00566 // iterator functions 00567 template <typename Type> 00568 inline typename array<Type>::iterator array<Type>::begin() throw() 00569 { 00570 return &(m_array[0]); 00571 } 00572 00573 template <typename Type> 00574 inline typename array<Type>::const_iterator array<Type>::begin() const throw() 00575 { 00576 return &(m_array[0]); 00577 } 00578 00579 template <typename Type> 00580 inline typename array<Type>::iterator array<Type>::end() throw() 00581 { 00582 return &(m_array[m_size]); 00583 } 00584 00585 template <typename Type> 00586 inline typename array<Type>::const_iterator array<Type>::end() const throw() 00587 { 00588 return &(m_array[m_size]); 00589 } 00590 00591 template <typename Type> 00592 inline typename array<Type>::reverse_iterator array<Type>::rbegin() throw() 00593 { 00594 return end(); 00595 } 00596 00597 template <typename Type> 00598 inline typename array<Type>::const_reverse_iterator array<Type>::rbegin() const throw() 00599 { 00600 return end(); 00601 } 00602 00603 template <typename Type> 00604 inline typename array<Type>::reverse_iterator array<Type>::rend() throw() 00605 { 00606 return begin(); 00607 } 00608 00609 template <typename Type> 00610 inline typename array<Type>::const_reverse_iterator array<Type>::rend() const throw() 00611 { 00612 return begin(); 00613 } 00614 00615 // comparisons (required by std. container definition) 00616 template <typename Type> 00617 inline bool array<Type>::operator == (const array<Type> & a_array) const throw() 00618 { 00619 return equal(begin(),end(),a_array.begin()); 00620 } 00621 00622 template <typename Type> 00623 inline bool array<Type>::operator != (const array<Type> & a_array) const throw() 00624 { 00625 return !(*this == a_array); 00626 } 00627 00628 template <typename Type> 00629 inline bool array<Type>::operator < (const array<Type> & a_array) const throw() 00630 { 00631 return lexicographical_compare(begin(),end(),a_array.begin(),a_array.end()); 00632 } 00633 00634 template <typename Type> 00635 inline bool array<Type>::operator > (const array<Type> & a_array) const throw() 00636 { 00637 return (a_array < *this); 00638 } 00639 00640 template <typename Type> 00641 inline bool array<Type>::operator <= (const array<Type> & a_array) const throw() 00642 { 00643 return !(*this > a_array); 00644 } 00645 00646 template <typename Type> 00647 inline bool array<Type>::operator >= (const array<Type> & a_array) const throw() 00648 { 00649 return !(*this < a_array); 00650 } 00651 00652 // swap (required by std. container definition) 00653 template <typename Type> 00654 void array<Type>::swap(array<Type> & a_source) throw() 00655 { 00656 // in this case, both arrays must be the same a_length 00657 validate_equals(m_size,a_source.m_size,LIBCOYOTL_LOCATION); 00658 00659 // use pointers for copy 00660 Type * target_ptr = m_array; 00661 Type * source_ptr = a_source.m_array; 00662 00663 for (size_t n = 0; n < m_size; ++n) 00664 { 00665 Type temp = *target_ptr; 00666 *target_ptr = *source_ptr; 00667 *source_ptr = temp; 00668 00669 ++target_ptr; 00670 ++source_ptr; 00671 } 00672 } 00673 00674 // number of elements 00675 template <typename Type> 00676 inline size_t array<Type>::size() const throw() 00677 { 00678 return m_size; 00679 } 00680 00681 // max_size (required by std. container definition) 00682 template <typename Type> 00683 inline size_t array<Type>::max_size() const throw() 00684 { 00685 return m_size; 00686 } 00687 00688 // empty (always false; required by std. container definition) 00689 template <typename Type> 00690 inline bool array<Type>::empty() const throw() 00691 { 00692 return false; 00693 } 00694 00695 }; 00696 00697 #endif
© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.