#include <cstddef>
#include <iostream>
template<typename Dst,typename Src>
Dst* pointer_cast(Src *ptr){
return static_cast<Dst*>(static_cast<void*>(ptr));
}
template<typename Dst,typename Src>
Dst* pointer_cast(Src const* ptr){
return static_cast<Dst*>(static_cast<void const*>(ptr));
}
class Vector{
protected:
char *data;
std::size_t elem_size;
Vector(std::size_t size) : data(new char[3*size]),elem_size(size){
}
char *at(std::size_t index){
return data + elem_size * index;
}
char const* at(std::size_t index) const{
return data + elem_size * index;
}
void doSomething();
};
void Vector::doSomething(){
//処理が隠蔽できる
}
template<typename T>
class Vector_ : Vector{
public:
Vector_() : Vector(sizeof(T)){
}
T &operator [](std::size_t index){
return *pointer_cast<T>(this->at(index));
}
T const& operator[](std::size_t index) const{
return *pointer_cast<T const>(this->at(index));
}
};
template<typename T>
std::ostream& operator <<(std::ostream& os,Vector_<T> const& v){
return os << '[' << v[0] << ',' << v[1] << ',' << v[2] << ']';
}
int main(){
Vector_<int> v;
v[0] = 1;
v[1] = 2;
v[2] = 3;
std::cout << v << std::endl;
Vector_<double> v2;
v2[0] = 0.0;
v2[1] = 3.14;
v2[2] = 2.71;
std::cout << v2 << std::endl;
return 0;
}
I2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlIDxpb3N0cmVhbT4KCnRlbXBsYXRlPHR5cGVuYW1lIERzdCx0eXBlbmFtZSBTcmM+CkRzdCogcG9pbnRlcl9jYXN0KFNyYyAqcHRyKXsKICAgIHJldHVybiBzdGF0aWNfY2FzdDxEc3QqPihzdGF0aWNfY2FzdDx2b2lkKj4ocHRyKSk7Cn0KdGVtcGxhdGU8dHlwZW5hbWUgRHN0LHR5cGVuYW1lIFNyYz4KRHN0KiBwb2ludGVyX2Nhc3QoU3JjIGNvbnN0KiBwdHIpewogICAgcmV0dXJuIHN0YXRpY19jYXN0PERzdCo+KHN0YXRpY19jYXN0PHZvaWQgY29uc3QqPihwdHIpKTsKfQoKY2xhc3MgVmVjdG9yewpwcm90ZWN0ZWQ6CiAgICBjaGFyICpkYXRhOwogICAgc3RkOjpzaXplX3QgZWxlbV9zaXplOwogICAgCiAgICBWZWN0b3Ioc3RkOjpzaXplX3Qgc2l6ZSkgOiBkYXRhKG5ldyBjaGFyWzMqc2l6ZV0pLGVsZW1fc2l6ZShzaXplKXsKICAgIH0KICAgIAogICAgY2hhciAqYXQoc3RkOjpzaXplX3QgaW5kZXgpewogICAgICAgIHJldHVybiBkYXRhICsgZWxlbV9zaXplICogaW5kZXg7CiAgICB9CiAgICBjaGFyIGNvbnN0KiBhdChzdGQ6OnNpemVfdCBpbmRleCkgY29uc3R7CiAgICAgICAgcmV0dXJuIGRhdGEgKyBlbGVtX3NpemUgKiBpbmRleDsKICAgIH0KCiAgICB2b2lkIGRvU29tZXRoaW5nKCk7Cn07CnZvaWQgVmVjdG9yOjpkb1NvbWV0aGluZygpewogICAgLy/lh6bnkIbjgYzpmqDolL3jgafjgY3jgosKfQp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpjbGFzcyBWZWN0b3JfIDogVmVjdG9yewpwdWJsaWM6CiAgICBWZWN0b3JfKCkgOiBWZWN0b3Ioc2l6ZW9mKFQpKXsKICAgIH0KICAgIAogICAgVCAmb3BlcmF0b3IgW10oc3RkOjpzaXplX3QgaW5kZXgpewogICAgICAgIHJldHVybiAqcG9pbnRlcl9jYXN0PFQ+KHRoaXMtPmF0KGluZGV4KSk7CiAgICB9CiAgICBUIGNvbnN0JiBvcGVyYXRvcltdKHN0ZDo6c2l6ZV90IGluZGV4KSBjb25zdHsKICAgICAgICByZXR1cm4gKnBvaW50ZXJfY2FzdDxUIGNvbnN0Pih0aGlzLT5hdChpbmRleCkpOwogICAgfQp9Owp0ZW1wbGF0ZTx0eXBlbmFtZSBUPgpzdGQ6Om9zdHJlYW0mIG9wZXJhdG9yIDw8KHN0ZDo6b3N0cmVhbSYgb3MsVmVjdG9yXzxUPiBjb25zdCYgdil7CiAgICByZXR1cm4gb3MgPDwgJ1snIDw8IHZbMF0gPDwgICcsJyA8PCB2WzFdIDw8ICcsJyA8PCB2WzJdIDw8ICddJzsKfQoKaW50IG1haW4oKXsKICAgIFZlY3Rvcl88aW50PiB2OwogICAgdlswXSA9IDE7CiAgICB2WzFdID0gMjsKICAgIHZbMl0gPSAzOwogICAgc3RkOjpjb3V0IDw8IHYgPDwgc3RkOjplbmRsOwogICAgCiAgICBWZWN0b3JfPGRvdWJsZT4gdjI7CiAgICB2MlswXSA9IDAuMDsKICAgIHYyWzFdID0gMy4xNDsKICAgIHYyWzJdID0gMi43MTsKICAgIHN0ZDo6Y291dCA8PCB2MiA8PCBzdGQ6OmVuZGw7CiAgICByZXR1cm4gMDsKfQo=