Skip to content

Instantly share code, notes, and snippets.

@grayed
Last active May 20, 2021 02:54
Show Gist options
  • Save grayed/97a3b912301bf594db6f902f95690068 to your computer and use it in GitHub Desktop.
Save grayed/97a3b912301bf594db6f902f95690068 to your computer and use it in GitHub Desktop.
#include "stdafx.h"
#include <array>
#include <exception>
#include <iostream>
#include <cstdint>
#include <string.h>
// AUTORESIZE как...
// 1. Параметр шаблона
// 2. Изменение поведения при наследовании
// 3. Переменная в самом классе Array
// AUTORESIZE == true -> при обращении за пределами size() дополнительное место выделяется
// AUTORESIZE == false -> при обращении за пределами size() кидается исключение
template<class T, bool AUTORESIZE = false, class SIZE = size_t>
class Array {
class ArrayData {
public:
ArrayData(SIZE size_) : size(size_), capacity(size_), refcnt(1) { p = new T[size]; }
~ArrayData() { delete[] p; }
T *p;
SIZE size, capacity, refcnt;
};
ArrayData *d;
public:
Array(SIZE size_ = 0) : d(new ArrayData(size_)) { }
Array(const Array &other) : d(other.d) {
d->refcnt++;
}
~Array() {
d->refcnt -= 1;
if (d->refcnt == 0)
delete d;
}
SIZE getSize() const { return d->size; }
const T *getData() const { return d->p; }
T *getData() { return d->p; }
T operator[](SIZE idx) const {
if (idx >= d->size)
throw std::invalid_argument("invalid index");
return d->p[idx];
}
T& operator[](SIZE idx) {
if (idx >= d->size)
resize(idx + 1);
return d->p[idx];
}
void resize(SIZE newSize) {
if (newSize <= d->capacity && d->refcnt == 1) {
d->size = newSize;
return;
}
if (d->refcnt == 1) {
T *newp = new T[newSize];
memcpy(newp, d->p, ((newSize < d->size) ? newSize : d->size) * sizeof(T));
delete[] d->p;
d->p = newp;
d->capacity = d->size = newSize;
} else {
ArrayData *tmp = new ArrayData(newSize);
memcpy(tmp->p, d->p, ((newSize < d->size) ? newSize : d->size) * sizeof(T));
d->refcnt--;
d = tmp;
}
}
};
int main(int argc, char* argv[])
{
Array<int> myarr(12);
Array<int> other = myarr;
Array<long, true, unsigned int> longarr;
Array<Array<int, true>> aa(12);
aa[1][24] = 123;
longarr[12] = 123;
std::cout << "Array of long has " << longarr.getSize() << " size" << std::endl;
myarr[45] = 123;
std::cout << "Array has " << myarr.getSize() << " elements, first one is " << myarr[0] << std::endl;
try {
myarr[30] = 42;
}
catch (std::invalid_argument ex) {
std::cerr << ex.what() << std::endl;
}
catch (int foo) {
}
// записать в журнал, показать ошибку пользователю
{ char ch; std::cin >> ch; }
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment