#include <iostream>
#include <memory>
#include <cassert>
struct Hoge {
int i;
public:
Hoge(int j) : i(j) {}
void print() const {
std::cout << i << std::endl;
}
};
template <class T, class Allocator = std::allocator<T> >
class MyVector {
int Elements;
int Num;
T* hp;
Allocator alloc;
public:
MyVector() : Elements(0), hp(0) {}
void push_back(const T& h) {
T* newmem = alloc.allocate(Elements + 1); // 要素を一つ増やすと再割当てが起きる可能性がある
std::uninitialized_copy(hp, hp + Elements, newmem); // 古い要素を新しいメモリーにコピーする
alloc.construct(newmem + Elements, h); // 追加された要素のコンストラクタ
// 再割当てが起きたと見なして古い要素を破棄・メモリを解放する
for (int i = 0; i < Elements; i++)
alloc.destroy(&hp[i]);
alloc.deallocate(hp, Elements);
Elements++;
Num++;
hp = newmem;
}
T pop_back() {
// std::assert(Elements != 0);
T tmp = hp[--Elements];
alloc.destroy(&hp[Elements]); // 要素を破棄(破棄してもメモリは解放されない事に注意、これがC++11でstd::shrink_to_fit()が用意された理由でもある)
return tmp;
}
int size() const {
return Elements;
}
T& operator[](int i) {
// std::assert(Elements != 0);
return hp[i];
}
~MyVector() {
for (int i = 0; i < Elements; i++)
alloc.destroy(&hp[i]);
alloc.deallocate(hp, Num);
}
};
int main()
{
MyVector<Hoge> mh;
mh.push_back(Hoge(1));
mh.push_back(Hoge(2));
std::cout << "size = " << mh.size() << std::endl;
mh[0].print();
mh[1].print();
mh.pop_back();
std::cout << "size = " << mh.size() << std::endl;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8Y2Fzc2VydD4KCnN0cnVjdCBIb2dlIHsKICBpbnQgaTsKcHVibGljOgogIEhvZ2UoaW50IGopIDogaShqKSB7fQogIHZvaWQgcHJpbnQoKSBjb25zdCB7CiAgICBzdGQ6OmNvdXQgPDwgaSA8PCBzdGQ6OmVuZGw7CiAgfQp9OwoKdGVtcGxhdGUgPGNsYXNzIFQsIGNsYXNzIEFsbG9jYXRvciA9IHN0ZDo6YWxsb2NhdG9yPFQ+ID4KY2xhc3MgTXlWZWN0b3IgewogIGludCBFbGVtZW50czsKICBpbnQgTnVtOwogIFQqIGhwOwogIEFsbG9jYXRvciBhbGxvYzsKcHVibGljOgogIE15VmVjdG9yKCkgOiBFbGVtZW50cygwKSwgaHAoMCkge30KICB2b2lkIHB1c2hfYmFjayhjb25zdCBUJiBoKSB7CiAgICBUKiBuZXdtZW0gPSBhbGxvYy5hbGxvY2F0ZShFbGVtZW50cyArIDEpOyAvLyDopoHntKDjgpLkuIDjgaTlopfjgoTjgZnjgajlho3libLlvZPjgabjgYzotbfjgY3jgovlj6/og73mgKfjgYzjgYLjgosKICAgIHN0ZDo6dW5pbml0aWFsaXplZF9jb3B5KGhwLCBocCArIEVsZW1lbnRzLCBuZXdtZW0pOyAvLyDlj6TjgYTopoHntKDjgpLmlrDjgZfjgYTjg6Hjg6Ljg6rjg7zjgavjgrPjg5Tjg7zjgZnjgosKICAgIGFsbG9jLmNvbnN0cnVjdChuZXdtZW0gKyBFbGVtZW50cywgaCk7IC8vIOi/veWKoOOBleOCjOOBn+imgee0oOOBruOCs+ODs+OCueODiOODqeOCr+OCvwogICAgLy8g5YaN5Ymy5b2T44Gm44GM6LW344GN44Gf44Go6KaL44Gq44GX44Gm5Y+k44GE6KaB57Sg44KS56C05qOE44O744Oh44Oi44Oq44KS6Kej5pS+44GZ44KLCiAgICBmb3IgKGludCBpID0gMDsgaSA8IEVsZW1lbnRzOyBpKyspCiAgICAgIGFsbG9jLmRlc3Ryb3koJmhwW2ldKTsKICAgIGFsbG9jLmRlYWxsb2NhdGUoaHAsIEVsZW1lbnRzKTsKICAgIEVsZW1lbnRzKys7CiAgICBOdW0rKzsKICAgIGhwID0gbmV3bWVtOwogIH0KICBUIHBvcF9iYWNrKCkgewovLyAgICBzdGQ6OmFzc2VydChFbGVtZW50cyAhPSAwKTsKICAgIFQgdG1wID0gaHBbLS1FbGVtZW50c107CiAgICBhbGxvYy5kZXN0cm95KCZocFtFbGVtZW50c10pOyAvLyDopoHntKDjgpLnoLTmo4Qo56C05qOE44GX44Gm44KC44Oh44Oi44Oq44Gv6Kej5pS+44GV44KM44Gq44GE5LqL44Gr5rOo5oSP44CB44GT44KM44GMQysrMTHjgadzdGQ6OnNocmlua190b19maXQoKeOBjOeUqOaEj+OBleOCjOOBn+eQhueUseOBp+OCguOBguOCiykKICAgIHJldHVybiB0bXA7CiAgfQogIGludCBzaXplKCkgY29uc3QgewogICAgcmV0dXJuIEVsZW1lbnRzOwogIH0KICBUJiBvcGVyYXRvcltdKGludCBpKSB7Ci8vICAgIHN0ZDo6YXNzZXJ0KEVsZW1lbnRzICE9IDApOwogICAgcmV0dXJuIGhwW2ldOwogIH0KICB+TXlWZWN0b3IoKSB7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IEVsZW1lbnRzOyBpKyspCiAgICAgIGFsbG9jLmRlc3Ryb3koJmhwW2ldKTsKICAgIGFsbG9jLmRlYWxsb2NhdGUoaHAsIE51bSk7CiAgfQp9OwoKaW50IG1haW4oKQp7CiAgTXlWZWN0b3I8SG9nZT4gbWg7CiAgbWgucHVzaF9iYWNrKEhvZ2UoMSkpOwogIG1oLnB1c2hfYmFjayhIb2dlKDIpKTsKICBzdGQ6OmNvdXQgPDwgInNpemUgPSAiIDw8IG1oLnNpemUoKSA8PCBzdGQ6OmVuZGw7CiAgbWhbMF0ucHJpbnQoKTsKICBtaFsxXS5wcmludCgpOwogIG1oLnBvcF9iYWNrKCk7CiAgc3RkOjpjb3V0IDw8ICJzaXplID0gIiA8PCBtaC5zaXplKCkgPDwgc3RkOjplbmRsOwp9