libcoyotl - A Library of C++ Tools

Created by Scott Robert Ladd at Coyote Gulch Productions.


array.h
1 //---------------------------------------------------------------------
2 // Algorithmic Conjurings @ http://www.coyotegulch.com
3 //
4 // array.h (libcoyotl)
5 //
6 // Templatized array classes compatible with STL containers and
7 // algorithms.
8 //---------------------------------------------------------------------
9 //
10 // Copyright 1990-2005 Scott Robert Ladd
11 //
12 // This program is free software; you can redistribute it and/or modify
13 // it under the terms of the GNU General Public License as published by
14 // the Free Software Foundation; either version 2 of the License, or
15 // (at your option) any later version.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the
24 // Free Software Foundation, Inc.
25 // 59 Temple Place - Suite 330
26 // Boston, MA 02111-1307, USA.
27 //
28 //-----------------------------------------------------------------------
29 //
30 // For more information on this software package, please visit
31 // Scott's web site, Coyote Gulch Productions, at:
32 //
33 // http://www.coyotegulch.com
34 //
35 //-----------------------------------------------------------------------
36 
37 #if !defined(LIBCOYOTL_ARRAY_H)
38 #define LIBCOYOTL_ARRAY_H
39 
40 // Microsoft Visual C++-specific pragmas
41 #if defined(_MSC_VER)
42 #pragma warning(disable : 4290 4101) // "exception specification ignored", "unused var"
43 #endif
44 
45 #include <cstddef> // for size_t
46 #include <algorithm> // for lexicographical_compare
47 
48 #include "validator.h" // validation functions
49 #include "realutil.h" // need min_of function
50 
51 #if defined(LIBCOYOTL_BOUNDS_CHECKING)
52 #include <stdexcept>
53 #include <sstream>
54 #define LIBCOYOTL_ARRAY_EXCEPTIONS validation_error<size_t>
55 #define LIBCOYOTL_ARRAY_CHECK_INDEX(n) validate_less(n,m_size,LIBCOYOTL_LOCATION);
56 #else
57 #define LIBCOYOTL_ARRAY_EXCEPTIONS
58 #define LIBCOYOTL_ARRAY_CHECK_INDEX(n)
59 #endif
60 
61 namespace libcoyotl
62 {
64 
71  template <typename Type>
72  class array
73  {
74  public:
76  typedef Type value_type;
77 
79  typedef Type * pointer;
80 
82  typedef const Type * const_pointer;
83 
85  typedef Type & reference;
86 
88  typedef const Type & const_reference;
89 
91  typedef ptrdiff_t difference_type;
92 
94  typedef size_t size_type;
95 
97  typedef Type * iterator;
98 
100  typedef const Type * const_iterator;
101 
103  typedef Type * reverse_iterator;
104 
106  typedef const Type * const_reverse_iterator;
107 
109 
113  array(size_t a_length);
114 
116 
122  array(size_t a_length, const Type & a_init_value);
123 
125 
129  array(const array<Type> & a_source);
130 
132 
138  array(size_t a_length, const Type * a_carray);
139 
141 
148  virtual ~array() throw();
149 
151 
155  array & operator = (const array<Type> & a_source) throw();
156 
158 
163  array & operator = (const Type & a_value) throw();
164 
166 
171  array & operator = (const Type * a_carray) throw();
172 
174 
180  const Type * c_array() const throw();
181 
183 
188  Type & operator [] (size_t n) throw(LIBCOYOTL_ARRAY_EXCEPTIONS);
189 
191 
196  Type operator [] (size_t n) const throw(LIBCOYOTL_ARRAY_EXCEPTIONS);
197 
199 
204  void append(const array<Type> & a_array);
205 
207 
211  iterator begin() throw();
212 
214 
218  const_iterator begin() const throw();
219 
221 
225  iterator end() throw();
226 
228 
232  const_iterator end() const throw();
233 
235 
239  iterator rbegin() throw();
240 
242 
246  const_iterator rbegin() const throw();
247 
249 
253  iterator rend() throw();
254 
256 
260  const_iterator rend() const throw();
261 
263 
269  bool operator == (const array<Type> & a_comparand) const throw();
270 
272 
278  bool operator != (const array<Type> & a_comparand) const throw();
279 
281 
287  bool operator < (const array<Type> & a_comparand) const throw();
288 
290 
296  bool operator <= (const array<Type> & a_comparand) const throw();
297 
299 
305  bool operator > (const array<Type> & a_comparand) const throw();
306 
308 
314  bool operator >= (const array<Type> & a_comparand) const throw();
315 
317 
322  void swap(array<Type> & a_source) throw();
323 
325 
330  size_t size() const throw();
331 
333 
338  size_t max_size() const throw();
339 
341 
346  bool empty() const throw();
347 
348  protected:
350  Type * m_array;
351 
353  size_t m_size;
354 
355  private:
356  // assign a single a_value to all elements
357  void assign_value(const Type & a_value) throw();
358 
359  // copy elements from a c-style array
360  void copy_carray(const Type * a_carray) throw();
361 
362  // copy elements from another array
363  void copy_array(const array<Type> & a_source) throw();
364  };
365 
366  // assign a single a_value to all elements
367  template <typename Type>
368  void array<Type>::assign_value(const Type & a_value) throw()
369  {
370  Type * element_ptr = m_array;
371 
372  for (size_t n = 0; n < m_size; ++n)
373  {
374  *element_ptr = a_value;
375  ++element_ptr;
376  }
377  }
378 
379  // copy elements from a c-style array
380  template <typename Type>
381  void array<Type>::copy_carray(const Type * a_carray) throw()
382  {
383  // use pointers for speed
384  Type * target_ptr = m_array;
385  const Type * carray_ptr = a_carray;
386 
387  for (size_t n = 0; n < m_size; ++n)
388  {
389  *target_ptr = *carray_ptr;
390  ++target_ptr;
391  ++carray_ptr;
392  }
393  }
394 
395  // copy elements from another array
396  template <typename Type>
397  void array<Type>::copy_array(const array<Type> & a_source) throw()
398  {
399  // find minimum a_length between the two arrays
400  size_t copy_length = min_of(m_size,a_source.m_size);
401 
402  // use pointers for speed
403  Type * target_ptr = m_array;
404  const Type * source_ptr = a_source.m_array;
405 
406  for (size_t n = 0; n < copy_length; ++n)
407  {
408  *target_ptr = *source_ptr;
409  ++target_ptr;
410  ++source_ptr;
411  }
412  }
413 
414  // default constructor
415  template <typename Type>
416  array<Type>::array(size_t a_length)
417  : m_array(NULL),
418  m_size(a_length)
419  {
420  // enforce lower limit on a_length
421  enforce_lower_limit(m_size,size_t(1));
422 
423  // allocate array
424  m_array = new Type [m_size];
425  }
426 
427  // a_value constructor
428  template <typename Type>
429  array<Type>::array(size_t a_length, const Type & a_init_value)
430  : m_array(NULL),
431  m_size(a_length)
432  {
433  // enforce lower limit on a_length
434  enforce_lower_limit(m_size,size_t(1));
435 
436  // allocate array
437  m_array = new Type [m_size];
438 
439  // assign values
440  assign_value(a_init_value);
441  }
442 
443  // copy constructor
444  template <typename Type>
445  array<Type>::array(const array<Type> & a_source)
446  : m_array(NULL),
447  m_size(a_source.m_size)
448  {
449  // allocate array
450  m_array = new Type [m_size];
451 
452  // copy a_source array
453  copy_array(a_source);
454  }
455 
456  // construct from C-style array
457  template <typename Type>
458  array<Type>::array(size_t a_length, const Type * a_carray)
459  : m_array(NULL),
460  m_size(a_length)
461  {
462  // validate a_source
463  validate_not(a_carray,(const Type *)NULL,LIBCOYOTL_LOCATION);
464 
465  // enforce lower limit on a_length
466  enforce_lower_limit(m_size,size_t(1));
467 
468  // allocate array
469  m_array = new Type [m_size];
470 
471  // copy elements of c array
472  copy_carray(a_carray);
473  }
474 
475  // destructor
476  template <typename Type>
478  {
479  // clean up resources
480  delete [] m_array;
481  m_array = NULL;
482  m_size = 0;
483  }
484 
485  // assignment operator
486  template <typename Type>
488  {
489  copy_array(a_source);
490  return *this;
491  }
492 
493  // assign all operator
494  template <typename Type>
495  array<Type> & array<Type>::operator = (const Type & a_value) throw()
496  {
497  assign_value(a_value);
498  return *this;
499  }
500 
501  // assign from C-style array
502  template <typename Type>
503  array<Type> & array<Type>::operator = (const Type * a_source) throw()
504  {
505  copy_carray(a_source);
506  return *this;
507  }
508 
509  // conversion to C-style array
510  template <typename Type>
511  inline const Type * array<Type>::c_array() const throw()
512  {
513  return m_array;
514  }
515 
516  // element access
517  template <typename Type>
518  inline Type & array<Type>::operator [] (size_t n) throw(LIBCOYOTL_ARRAY_EXCEPTIONS)
519  {
520  LIBCOYOTL_ARRAY_CHECK_INDEX(n)
521  return m_array[n];
522  }
523 
524  template <typename Type>
525  inline Type array<Type>::operator [] (size_t n) const throw(LIBCOYOTL_ARRAY_EXCEPTIONS)
526  {
527  LIBCOYOTL_ARRAY_CHECK_INDEX(n)
528  return m_array[n];
529  }
530 
531  // appending
532  template <typename Type>
533  void array<Type>::append(const array<Type> & other)
534  {
535  size_t new_size = m_size + other.m_size;
536  Type * new_array = new Type[new_size];
537 
538  Type * target = new_array;
539  Type * a_source = m_array;
540  size_t n;
541 
542  // copy from this array
543  for (n = 0; n < m_size; ++n)
544  {
545  *target = *a_source;
546  ++target;
547  ++a_source;
548  }
549 
550  // copy from other array
551  a_source = other.m_array;
552 
553  for (n = 0; n < other.m_size; ++n)
554  {
555  *target = *a_source;
556  ++target;
557  ++a_source;
558  }
559 
560  // set this to use new array, destroying old one
561  m_size = new_size;
562  delete [] m_array;
563  m_array = new_array;
564  }
565 
566  // iterator functions
567  template <typename Type>
568  inline typename array<Type>::iterator array<Type>::begin() throw()
569  {
570  return &(m_array[0]);
571  }
572 
573  template <typename Type>
574  inline typename array<Type>::const_iterator array<Type>::begin() const throw()
575  {
576  return &(m_array[0]);
577  }
578 
579  template <typename Type>
580  inline typename array<Type>::iterator array<Type>::end() throw()
581  {
582  return &(m_array[m_size]);
583  }
584 
585  template <typename Type>
586  inline typename array<Type>::const_iterator array<Type>::end() const throw()
587  {
588  return &(m_array[m_size]);
589  }
590 
591  template <typename Type>
593  {
594  return end();
595  }
596 
597  template <typename Type>
599  {
600  return end();
601  }
602 
603  template <typename Type>
605  {
606  return begin();
607  }
608 
609  template <typename Type>
611  {
612  return begin();
613  }
614 
615  // comparisons (required by std. container definition)
616  template <typename Type>
617  inline bool array<Type>::operator == (const array<Type> & a_array) const throw()
618  {
619  return equal(begin(),end(),a_array.begin());
620  }
621 
622  template <typename Type>
623  inline bool array<Type>::operator != (const array<Type> & a_array) const throw()
624  {
625  return !(*this == a_array);
626  }
627 
628  template <typename Type>
629  inline bool array<Type>::operator < (const array<Type> & a_array) const throw()
630  {
631  return lexicographical_compare(begin(),end(),a_array.begin(),a_array.end());
632  }
633 
634  template <typename Type>
635  inline bool array<Type>::operator > (const array<Type> & a_array) const throw()
636  {
637  return (a_array < *this);
638  }
639 
640  template <typename Type>
641  inline bool array<Type>::operator <= (const array<Type> & a_array) const throw()
642  {
643  return !(*this > a_array);
644  }
645 
646  template <typename Type>
647  inline bool array<Type>::operator >= (const array<Type> & a_array) const throw()
648  {
649  return !(*this < a_array);
650  }
651 
652  // swap (required by std. container definition)
653  template <typename Type>
654  void array<Type>::swap(array<Type> & a_source) throw()
655  {
656  // in this case, both arrays must be the same a_length
657  validate_equals(m_size,a_source.m_size,LIBCOYOTL_LOCATION);
658 
659  // use pointers for copy
660  Type * target_ptr = m_array;
661  Type * source_ptr = a_source.m_array;
662 
663  for (size_t n = 0; n < m_size; ++n)
664  {
665  Type temp = *target_ptr;
666  *target_ptr = *source_ptr;
667  *source_ptr = temp;
668 
669  ++target_ptr;
670  ++source_ptr;
671  }
672  }
673 
674  // number of elements
675  template <typename Type>
676  inline size_t array<Type>::size() const throw()
677  {
678  return m_size;
679  }
680 
681  // max_size (required by std. container definition)
682  template <typename Type>
683  inline size_t array<Type>::max_size() const throw()
684  {
685  return m_size;
686  }
687 
688  // empty (always false; required by std. container definition)
689  template <typename Type>
690  inline bool array<Type>::empty() const throw()
691  {
692  return false;
693  }
694 
695 };
696 
697 #endif
bool operator>(const array< Type > &a_comparand) const
Greater-than operator.
Definition: array.h:635
bool operator!=(const array< Type > &a_comparand) const
Inequality operator.
Definition: array.h:623
Type value_type
Type of an array element.
Definition: array.h:76
Type * pointer
type of a pointer to an element
Definition: array.h:79
const Type * c_array() const
Conversion to C-style array.
Definition: array.h:511
size_t max_size() const
Maximum container size.
Definition: array.h:683
iterator begin()
Obtain beginning-of-sequence iterator.
Definition: array.h:568
Type & operator[](size_t n)
Element access.
Definition: array.h:518
bool operator>=(const array< Type > &a_comparand) const
Greater-than-or-equal-to operator.
Definition: array.h:647
bool operator<(const array< Type > &a_comparand) const
Less-than operator.
Definition: array.h:629
iterator rend()
Obtain end-of-sequence reverse iterator.
Definition: array.h:604
const Type * const_reverse_iterator
Constant reverse iterator type.
Definition: array.h:106
Type * iterator
Iterator type.
Definition: array.h:97
size_t m_size
Length of the array.
Definition: array.h:353
iterator rbegin()
Obtain beginning-of-sequence reverse iterator.
Definition: array.h:592
void append(const array< Type > &a_array)
Appending arrays.
Definition: array.h:533
bool operator==(const array< Type > &a_comparand) const
Equals operator.
Definition: array.h:617
bool operator<=(const array< Type > &a_comparand) const
Less-than-or-equal-to operator.
Definition: array.h:641
Type * m_array
Underlying allocated array.
Definition: array.h:350
size_t size_type
Size type for indexing array elements.
Definition: array.h:94
Definition: array.h:61
virtual ~array()
Virtual destructor.
Definition: array.h:477
ptrdiff_t difference_type
Difference type between two element pointers.
Definition: array.h:91
iterator end()
Obtain end-of-sequence iterator.
Definition: array.h:580
const Type * const_pointer
Type of a constant pointer to an element.
Definition: array.h:82
Type * reverse_iterator
Reverse iterator type.
Definition: array.h:103
array(size_t a_length)
Default constructor.
Definition: array.h:416
const Type & const_reference
Type of a constant reference to an element.
Definition: array.h:88
Type & reference
Type of a reference to an element.
Definition: array.h:85
void swap(array< Type > &a_source)
Exchanges the corresponding elements of two arrays.
Definition: array.h:654
array & operator=(const array< Type > &a_source)
Assignment operator.
Definition: array.h:487
bool empty() const
Empty container check.
Definition: array.h:690
const Type * const_iterator
Constant iterator type.
Definition: array.h:100
A STL-compatible array class.
Definition: array.h:72
size_t size() const
Number of elements.
Definition: array.h:676

© 1996-2005 Scott Robert Ladd. All rights reserved.
HTML documentation generated by Dimitri van Heesch's excellent Doxygen tool.