-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArray.cpp
More file actions
201 lines (180 loc) · 6.17 KB
/
Copy pathArray.cpp
File metadata and controls
201 lines (180 loc) · 6.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
// This code was written by Michael Warren on April 10, 2014. If you have any questions, concerns, or suggestions, please e-mail him at mwarren04011990@gmail.com
// modified: September 5, 2016
#include "Array.h"
#include <iostream>
#include <new>
#include <stdexcept>
#include <typeinfo>
// header files of supported data types
#include "IntegerGroup.h"
#include "IntegerRing.h"
template <typename Object>
Array<Object>::Array()
{
this->internalDataStorage = 0;
this->length = 0;
}
template <typename Object>
Array<Object>::Array(unsigned arraySize)
{
//check the requested arraySize; it should NOT be greater than the capacity of Array
if (arraySize < Array<Object>::capacity)
{
this->length = arraySize;
this->internalDataStorage = new(std::nothrow) Object[arraySize];
}
else
{
std::string reason = "Requested too many elements. Maximum capacity: " +
Array<Object>::intToString(Array<Object>::capacity);
throw std::invalid_argument(reason);
}
}
template <typename Object>
Array<Object>::Array(const Array& anotherArray)
: length(anotherArray.length)
{
// perform deep copy
this->internalDataStorage = new(std::nothrow) Object[length];
for (unsigned j = 0; j < length; j++)
this->internalDataStorage[j] = anotherArray.internalDataStorage[j];
}
template <typename Object>
Array<Object>& Array<Object>::operator=(const Array& otherArray)
{
// if the length of *this is different from the length of otherArray
if (this->length != otherArray.length)
{
// set this->internalDataStorage to 0 (or delete it)
delete[] this->internalDataStorage;
// re-initialize it
this->internalDataStorage = new(std::nothrow) Object[otherArray.length];
// set this->length to otherArray.length
this->length = otherArray.length;
}
// perform deep copy of otherArray
for (unsigned j = 0; j < this->length; j++)
this->internalDataStorage[j] = otherArray.internalDataStorage[j];
// return *this
return *this;
}
template <typename Object>
const std::string Array<Object>::intToString(int intToConvert)
{
std::string intRepresentation = "";
int power = 9, powerOfTen = 1, digit = 0;
//setting the powerOfTen to pow(10,9), in a more reliable way
for (int j = 1; j <= power; j++)
powerOfTen *= 10;
//find the first non-zero digit
while ((digit = intToConvert / powerOfTen) == 0)
{
powerOfTen /= 10;
power--;
}
//appending the actual digits to intRepresentation (including the current digit)
while ((power--) >= 0)
{
//appending current digit to intRepresentation
intRepresentation += (char)(0x30 + ((intToConvert / powerOfTen) % 10));
powerOfTen /= 10;
}
return intRepresentation;
}
template <typename Object>
Array<Object>::~Array()
{
if (this->internalDataStorage != 0)
delete[] this->internalDataStorage;
}
// for knowing the size of the array (a typical C/C++ problem solved with the aid of typenames)
template <typename Object> unsigned Array<Object>::getLength() const { return this->length; }
// gets the type of data this Array holds
template <typename Object> std::string Array<Object>::getArrayType() const { return typeid(Object).name(); }
// for setting the Object at a position in an Array
template <typename Object>
void Array<Object>::setElementAt(unsigned index, const Object& newObjectValue)
{
//check the index
if (index >= this->length)
{
std::string explanation = "Index out of bounds. Array's length is: " + Array<Object>::intToString(this->length);
throw std::invalid_argument(explanation);
}
//setting the element
this->internalDataStorage[index] = newObjectValue;
}
// for fetching the current Object
template <typename Object> Object& Array<Object>::operator[](unsigned index)
{
//check the index against the size of the array
if (index >= this->length)
throw std::invalid_argument("Array index out-of-bounds.");
else
return this->internalDataStorage[index];
}
// the const version of the function above
template <typename Object>
const Object& Array<Object>::operator[](unsigned index) const
{
// check the index
if (index >= this->getLength())
{
throw std::invalid_argument("Array index out-of-bounds.");
}
return this->internalDataStorage[index];
}
// for swapping elements
template <typename Object>
void Array<Object>::swapElements(unsigned a, unsigned b)
{
if (a != b)
{
Object temp = (*this)[a];
(*this)[a] = (*this)[b];
(*this)[b] = temp;
}
}
// a maximum capacity for ALL Arrays; if this value is exceeded, the Array object will fail to be created
template <typename Object> const unsigned Array<Object>::capacity = 25000;
//comparison operators
template <typename Object>
bool Array<Object>::operator==(const Array<Object>& anotherArray) const
{
//the two should equal each other in size
if (this->getLength() != anotherArray.getLength()) return false;
//if the two Arrays are equal to each other, then ALL of their respective contents should equal each other
for (int index = 0; index < this->getLength(); index++)
if (this->internalDataStorage[index] != anotherArray[index])
return false;
//the code has reached here; the two Arrays ARE equal
return true;
}
template <typename Object>
bool Array<Object>::operator!=(const Array<Object>& anotherArray) const { return !((*this)==anotherArray); }
//for printing an Array
template <typename Object>
std::ostream& operator<<(std::ostream& outputStream, const Array<Object>& theArray)
{
outputStream << "{ ";
for (unsigned j = 0; j < theArray.getLength(); j++)
{
outputStream << theArray[j];
if (j < theArray.getLength() - 1)
outputStream << ", ";
}
return (outputStream << " }");
}
//supported type declarations go here
template class Array<int>;
template class Array<unsigned>;
template class Array<long>;
template class Array<float>;
template class Array<double>;
template class Array<long double>;
template class Array<char>;
template class Array<std::string>;
template class Array<bool>;
template class Array<IntegerGroup::GroupElement>;
//template class Array<IntegerRing::Element>;
template class Array<Array<int> >;