#include <iostream>
#include <memory>
#include <type_traits>
template <typename T>
struct SelectDeleter {
void operator()(T* t) {
std::cout << "generic deleter" << std::endl;
delete t;
}
};
template <typename T>
struct SelectDeleter<T[]> {
void operator()(T* t) {
std::cout << "array deleter" << std::endl;
delete[] t;
};
};
template <typename T, typename Deleter = SelectDeleter<T>>
struct foobar {
template <typename K>
struct SelectPtr {
using Ptr = K*;
};
template <typename K>
struct SelectPtr<K[]> {
using Ptr = K*;
};
using Ptr = typename SelectPtr<T>::Ptr;
foobar(Ptr p) : ptr(p) {
}
~foobar() {
Deleter()(ptr);
}
Ptr ptr;
};
int main() {
foobar<int> f1( new int(42) );
foobar<int[]> f2( new int[42] );
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8bWVtb3J5PgojaW5jbHVkZSA8dHlwZV90cmFpdHM+Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4Kc3RydWN0IFNlbGVjdERlbGV0ZXIgewogIHZvaWQgb3BlcmF0b3IoKShUKiB0KSB7CiAgICBzdGQ6OmNvdXQgPDwgImdlbmVyaWMgZGVsZXRlciIgPDwgc3RkOjplbmRsOwogICAgZGVsZXRlIHQ7CiAgfQp9OwoKdGVtcGxhdGUgPHR5cGVuYW1lIFQ+CnN0cnVjdCBTZWxlY3REZWxldGVyPFRbXT4gewogIHZvaWQgb3BlcmF0b3IoKShUKiB0KSB7CiAgICBzdGQ6OmNvdXQgPDwgImFycmF5IGRlbGV0ZXIiIDw8IHN0ZDo6ZW5kbDsKICAgIGRlbGV0ZVtdIHQ7CiAgfTsKfTsKCnRlbXBsYXRlIDx0eXBlbmFtZSBULCB0eXBlbmFtZSBEZWxldGVyID0gU2VsZWN0RGVsZXRlcjxUPj4Kc3RydWN0IGZvb2JhciB7CgogIHRlbXBsYXRlIDx0eXBlbmFtZSBLPgogIHN0cnVjdCBTZWxlY3RQdHIgewogICAgdXNpbmcgUHRyID0gSyo7CiAgfTsKCiAgdGVtcGxhdGUgPHR5cGVuYW1lIEs+CiAgc3RydWN0IFNlbGVjdFB0cjxLW10+IHsKICAgIHVzaW5nIFB0ciA9IEsqOwogIH07CgogIHVzaW5nIFB0ciA9IHR5cGVuYW1lIFNlbGVjdFB0cjxUPjo6UHRyOwogIAogIGZvb2JhcihQdHIgcCkgOiBwdHIocCkgewogIH0KICAKICB+Zm9vYmFyKCkgewogICAgRGVsZXRlcigpKHB0cik7CiAgfQoKICBQdHIgcHRyOwp9OwoKaW50IG1haW4oKSB7CiAgZm9vYmFyPGludD4gZjEoIG5ldyBpbnQoNDIpICk7CiAgZm9vYmFyPGludFtdPiBmMiggbmV3IGludFs0Ml0gKTsKfQo=