mirror of
https://git.adityakumar.xyz/data-structures.git
synced 2024-12-23 03:52:53 +00:00
123 lines
2.9 KiB
C++
123 lines
2.9 KiB
C++
|
#include <iostream>
|
||
|
#include <sstream>
|
||
|
#include <algorithm>
|
||
|
#include <memory>
|
||
|
|
||
|
template<class T> class dynamic_array {
|
||
|
private:
|
||
|
std::shared_ptr<T> data {};
|
||
|
size_t n {};
|
||
|
|
||
|
public:
|
||
|
dynamic_array(size_t n) {
|
||
|
this -> n = n;
|
||
|
data = std::make_shared<T[]>(n);
|
||
|
}
|
||
|
|
||
|
dynamic_array(const dynamic_array<T>& other) {
|
||
|
n = other.n;
|
||
|
data = std::make_shared<T[]>(n);
|
||
|
|
||
|
/* Here we perform a deep copy */
|
||
|
for (size_t i {}; i < n; ++i) data[i] = other[i];
|
||
|
}
|
||
|
|
||
|
T& operator[](int index) {
|
||
|
return data.get() + index;
|
||
|
}
|
||
|
|
||
|
const T& operator[](int index) const {
|
||
|
return data[index];
|
||
|
}
|
||
|
|
||
|
T& at(size_t index) {
|
||
|
if (index < n) return data[index];
|
||
|
throw "Index out of range";
|
||
|
}
|
||
|
|
||
|
size_t size() const {
|
||
|
return n;
|
||
|
}
|
||
|
|
||
|
~dynamic_array() = default;
|
||
|
|
||
|
std::shared_ptr<T> begin() {
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
const std::shared_ptr<T> begin() const {
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
std::shared_ptr<T> end() {
|
||
|
return data + n;
|
||
|
}
|
||
|
|
||
|
const std::shared_ptr<T> end() const {
|
||
|
return data + n;
|
||
|
}
|
||
|
|
||
|
friend dynamic_array<T> operator+(const dynamic_array<T>& arr1, dynamic_array<T>& arr2) {
|
||
|
dynamic_array<T> result(arr1.size() + arr2.size());
|
||
|
std::copy(arr1.begin(), arr1.end(), result.begin());
|
||
|
std::copy(arr2.begin(), arr2.end(), result.begin() + arr1.size());
|
||
|
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
std::string to_string(const std::string& sep = ", ") {
|
||
|
if (n == 0) return "";
|
||
|
std::ostringstream os {};
|
||
|
os << data.get();
|
||
|
|
||
|
for (size_t i {1}; i < n; ++i) os << sep << data.get() + i;
|
||
|
|
||
|
return os.str();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
struct student {
|
||
|
std::string name {};
|
||
|
size_t standard {};
|
||
|
};
|
||
|
|
||
|
std::ostream& operator<<(std::ostream& os, const student& s) {
|
||
|
return (os << "[Name: " << s.name << ", Standard: " << s.standard << "]");
|
||
|
}
|
||
|
|
||
|
int main() {
|
||
|
size_t nStudents {};
|
||
|
std::cout << "Enter number of students in class 1: ";
|
||
|
std::cin >> nStudents;
|
||
|
|
||
|
dynamic_array<student> class1(nStudents);
|
||
|
for (size_t i {}; i < nStudents; ++i) {
|
||
|
std::cout << "Enter name and class of student " << i + 1 << ": ";
|
||
|
std::string name {};
|
||
|
size_t standard {};
|
||
|
std::cin >> name >> standard;
|
||
|
class1[i] = student {name, standard};
|
||
|
}
|
||
|
|
||
|
// Now, let's tro to access the student out of range in the array
|
||
|
try {
|
||
|
class1[nStudents] =student{"John", 8}; // No exception, endeffined behaviour
|
||
|
std::cout << "class1 student set out of range without exception" << std::endl;
|
||
|
class1.at(nStudents) = student{"John", 8}; // Will throw exception
|
||
|
}
|
||
|
catch(...) {
|
||
|
std::cout << "Exception caught" << std::endl;
|
||
|
}
|
||
|
|
||
|
auto class2 = class1; // Deep copy
|
||
|
|
||
|
std::cout << "Second class after initialized using first array: " << class2.to_string() << std::endl;
|
||
|
|
||
|
auto class3 = class1 + class2; // Combines both classes and creates a bigger one
|
||
|
|
||
|
std::cout << "Combined class: ";
|
||
|
std::cout << class3.to_string() << std::endl;
|
||
|
|
||
|
return 0;
|
||
|
}
|