• Source
    1. #include <iostream>
    2. #include <memory>
    3.  
    4. #include <boost/shared_ptr.hpp>
    5.  
    6. namespace {
    7. template<class SharedPointer> struct Holder {
    8. SharedPointer p;
    9.  
    10. Holder(const SharedPointer &p) : p(p) {}
    11. Holder(const Holder &other) : p(other.p) {}
    12. Holder(Holder &&other) : p(std::move(other.p)) {}
    13.  
    14. void operator () (...) { p.reset(); }
    15. };
    16. }
    17.  
    18. template<class T> std::shared_ptr<T> to_std_ptr(const boost::shared_ptr<T> &p) {
    19. typedef Holder<std::shared_ptr<T>> H;
    20. if(H *h = boost::get_deleter<H, T>(p)) {
    21. std::cout << "Unwrapping boost::shared_ptr<" << typeid(T).name() << ">" << std::endl;
    22. return h->p;
    23. } else {
    24. std::cout << "Wrapping boost::shared_ptr<" << typeid(T).name() << ">" << std::endl;
    25. return std::shared_ptr<T>(p.get(), Holder<boost::shared_ptr<T>>(p));
    26. }
    27. }
    28.  
    29. template<class T> boost::shared_ptr<T> to_boost_ptr(const std::shared_ptr<T> &p){
    30. typedef Holder<boost::shared_ptr<T>> H;
    31. if(H * h = std::get_deleter<H, T>(p)) {
    32. std::cout << "Unwrapping std::shared_ptr<" << typeid(T).name() << ">" << std::endl;
    33. return h->p;
    34. } else {
    35. std::cout << "Wrapping std::shared_ptr<" << typeid(T).name() << ">" << std::endl;
    36. return boost::shared_ptr<T>(p.get(), Holder<std::shared_ptr<T>>(p));
    37. }
    38. }
    39.  
    40. template<class T>
    41. class Foo {
    42. public:
    43. virtual void foo() = 0;
    44. T value;
    45. };
    46.  
    47. template<class T>
    48. class Bar : public Foo<T> {
    49. public:
    50. void foo() {}
    51. };
    52.  
    53. using namespace std;
    54.  
    55. int main() {
    56. // your code goes here
    57. std::shared_ptr<Foo<int>> p(new Bar<int>);
    58. auto b = to_boost_ptr(p);
    59. auto p2 = to_std_ptr(b);
    60.  
    61. b = boost::shared_ptr<Foo<int>>(new Bar<int>);
    62. p2 = to_std_ptr(b);
    63.  
    64. return 0;
    65. }
    66.