array.h
Go to the documentation of this file.
1 // Copyright (C) 2007 Peter Carbonetto. All Rights Reserved.
2 // This code is published under the Eclipse Public License.
3 //
4 // Author: Peter Carbonetto
5 // Dept. of Computer Science
6 // University of British Columbia
7 // May 19, 2007
8 
9 #ifndef INCLUDE_ARRAY
10 #define INCLUDE_ARRAY
11 
12 #include "matlabexception.h"
13 #include <string.h>
14 
15 // Function definitions.
16 // ---------------------------------------------------------------
17 template <class Type> void copymemory (const Type* source, Type* dest,
18  int length) {
19  memcpy(dest,source,sizeof(Type)*length);
20 }
21 
22 // Class Array
23 // ---------------------------------------------------------------
24 // An Array object stores a collection of ordered elements. The key
25 // aspect of Array objects is that they do not necessarily achieve
26 // encapsulation; they do not necessarily retain independent
27 // ownership of their data. That is, the data could be modified
28 // externally by another agent. This behaviour is determined by the
29 // data member "owner". If "owner" is false, the array does not take
30 // care of allocation and deallocation of the data in memory.
31 //
32 // Copy assignment behaves different than usual---it copies the
33 // data, but requires that the destination already have the proper
34 // resources allocated in memory.
35 //
36 // The copy constructor performs a shallow copy.
37 template <class Type> class Array {
38  public:
39 
40  // This constructor allocates memory for an array of elements of
41  // the specificed length.
42  explicit Array (int length);
43 
44  // This constructor is set to point to an already existing
45  // array. As such, it does not gain ownership of the elements.
46  Array (Type* data, int length);
47 
48  // The copy constructor performs a shallow copy, so that both
49  // arrays share the same copy of the data.
50  Array (const Array<Type>& source);
51 
52  // The destructor.
53  ~Array();
54 
55  // Set all the elements of the array to the specified value.
56  void setvalue (const Type& value);
57 
58  // Copy the elements to from the source array. Both the source and
59  // destination array must have the same length.
60  void inject (const Type* source);
61  void inject (const Array<Type>& source);
62  Array<Type>& operator= (const Type* source);
63  Array<Type>& operator= (const Array<Type>& source);
64 
65  // Copy the elements to the location in memory pointed to by
66  // "dest". It is assumed that sufficient memory is allocated for
67  // the destination.
68  void copyto (Type* dest) const;
69 
70  // Get the number of elements in the array.
71  int length() const { return n; };
72 
73  // Elements of an array A can be accessed the subscript operator;
74  // e.g. A[i]. For the sake of efficiency, no checks are made to
75  // ensure that the subscripting is legal. It is up to the user to
76  // ensure that i is non-negative and less than A.length(). Note
77  // that subscripts, as per C++ convention, start at 0.
78  Type& operator[] (int i);
79  const Type& operator[] (int i) const;
80 
81  // Returns true if the two arrays have the same dimensions
82  // (i.e. the same lengths).
83  bool operator== (const Array<Type>& a) const { return n == a.n; };
84  bool operator!= (const Array<Type>& a) const { return !(*this == a); };
85 
86 protected:
87  Type* elems;
88  int n; // The number of elements in the array.
89  bool owner; // Whether the object has ownership of the data.
90 };
91 
92 // Function definitions for class Array.
93 // -----------------------------------------------------------------
94 template <class Type> Array<Type>::Array (int length) {
95  n = length;
96  owner = true;
97  elems = 0;
98  elems = new Type[length];
99 }
100 
101 template <class Type> Array<Type>::Array (Type* data, int length) {
102  n = length;
103  owner = false;
104  elems = data;
105 }
106 
107 template <class Type> Array<Type>::Array (const Array<Type>& source) {
108  n = source.n;
109  owner = false;
110  elems = source.elems;
111 }
112 
113 template <class Type> Array<Type>::~Array () {
114  if (owner && elems)
115  delete[] elems;
116 }
117 
118 template <class Type> void Array<Type>::setvalue (const Type& value) {
119  for (int i = 0; i < n; i++)
120  elems[i] = value;
121 }
122 
123 template <class Type> void Array<Type>::inject (const Type* source) {
124 
125  // Check for self-assignment. If there is self-assignment, there
126  // is no need to copy because the objects share the same data!
127  if (elems != source)
128  copymemory<Type>(source,elems,n);
129 }
130 
131 template <class Type> void Array<Type>::inject (const Array<Type>& source) {
132  if (n != source.n)
133  throw MatlabException("Unable to perform copy; arrays have \
134 different lengths");
135  inject(source.elems);
136 }
137 
138 template <class Type> Array<Type>& Array<Type>::operator=
139 (const Type* source) {
140  inject(source);
141  return *this;
142 }
143 
144 template <class Type> Array<Type>& Array<Type>::operator=
145 (const Array<Type>& source) {
146  inject(source);
147  return *this;
148 }
149 
150 template <class Type> void Array<Type>::copyto (Type* dest) const {
151  Array destarray(dest,n);
152  destarray.inject(*this);
153 }
154 
155 template <class Type> Type& Array<Type>::operator[] (int i) {
156  return elems[i];
157 }
158 
159 template <class Type> const Type& Array<Type>::operator[] (int i) const {
160  return elems[i];
161 }
162 
163 #endif