#include <iostream>
#include <memory>
#include <boost/shared_ptr.hpp>
namespace {
template<class SharedPointer> struct Holder {
SharedPointer p;
Holder(const SharedPointer &p) : p(p) {}
Holder(const Holder &other) : p(other.p) {}
Holder(Holder &&other) : p(std::move(other.p)) {}
void operator () (...) { p.reset(); }
};
}
template<class T> std::shared_ptr<T> to_std_ptr(const boost::shared_ptr<T> &p) {
typedef Holder<std::shared_ptr<T>> H;
if(H *h = boost::get_deleter<H, T>(p)) {
std::cout << "Unwrapping boost::shared_ptr<" << typeid(T).name() << ">" << std::endl;
return h->p;
} else {
std::cout << "Wrapping boost::shared_ptr<" << typeid(T).name() << ">" << std::endl;
return std::shared_ptr<T>(p.get(), Holder<boost::shared_ptr<T>>(p));
}
}
template<class T> boost::shared_ptr<T> to_boost_ptr(const std::shared_ptr<T> &p){
typedef Holder<boost::shared_ptr<T>> H;
if(H * h = std::get_deleter<H, T>(p)) {
std::cout << "Unwrapping std::shared_ptr<" << typeid(T).name() << ">" << std::endl;
return h->p;
} else {
std::cout << "Wrapping std::shared_ptr<" << typeid(T).name() << ">" << std::endl;
return boost::shared_ptr<T>(p.get(), Holder<std::shared_ptr<T>>(p));
}
}
template<class T>
class Foo {
public:
virtual void foo() = 0;
T value;
};
template<class T>
class Bar : public Foo<T> {
public:
void foo() {}
};
using namespace std;
int main() {
// your code goes here
std::shared_ptr<Foo<int>> p(new Bar<int>);
auto b = to_boost_ptr(p);
auto p2 = to_std_ptr(b);
b = boost::shared_ptr<Foo<int>>(new Bar<int>);
p2 = to_std_ptr(b);
return 0;
}