1 /*
2 Copyright 2017 Glen Joseph Fernandes
3 (glenjofe@gmail.com)
4 
5 Distributed under the Boost Software License, Version 1.0.
6 (http://www.boost.org/LICENSE_1_0.txt)
7 */
8 #include <boost/config.hpp>
9 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
10     !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
11 #include <boost/core/lightweight_test.hpp>
12 #include <boost/smart_ptr/enable_shared_from_this.hpp>
13 #include <boost/smart_ptr/make_local_shared.hpp>
14 
15 template<class T = void>
16 struct creator {
17     typedef T value_type;
18 
19     template<class U>
20     struct rebind {
21         typedef creator<U> other;
22     };
23 
creatorcreator24     creator() { }
25 
26     template<class U>
creatorcreator27     creator(const creator<U>&) { }
28 
allocatecreator29     T* allocate(std::size_t size) {
30         return static_cast<T*>(::operator new(sizeof(T) * size));
31     }
32 
deallocatecreator33     void deallocate(T* ptr, std::size_t) {
34         ::operator delete(ptr);
35     }
36 };
37 
38 template<class T, class U>
39 inline bool
operator ==(const creator<T> &,const creator<U> &)40 operator==(const creator<T>&, const creator<U>&)
41 {
42     return true;
43 }
44 
45 template<class T, class U>
46 inline bool
operator !=(const creator<T> &,const creator<U> &)47 operator!=(const creator<T>&, const creator<U>&)
48 {
49     return false;
50 }
51 
52 class type
53     : public boost::enable_shared_from_this<type> {
54 public:
55     static unsigned instances;
56 
type()57     type() {
58         ++instances;
59     }
60 
~type()61     ~type() {
62         --instances;
63     }
64 
65 private:
66     type(const type&);
67     type& operator=(const type&);
68 };
69 
70 unsigned type::instances = 0;
71 
main()72 int main()
73 {
74     BOOST_TEST(type::instances == 0);
75     {
76         boost::local_shared_ptr<type[]> result =
77             boost::allocate_local_shared<type[]>(creator<type>(), 3);
78         try {
79             result[0].shared_from_this();
80             BOOST_ERROR("shared_from_this did not throw");
81         } catch (...) {
82             BOOST_TEST(type::instances == 3);
83         }
84     }
85     BOOST_TEST(type::instances == 0);
86     {
87         boost::local_shared_ptr<type[]> result =
88             boost::allocate_local_shared_noinit<type[]>(creator<>(), 3);
89         try {
90             result[0].shared_from_this();
91             BOOST_ERROR("shared_from_this did not throw");
92         } catch (...) {
93             BOOST_TEST(type::instances == 3);
94         }
95     }
96     return boost::report_errors();
97 }
98 #else
main()99 int main()
100 {
101     return 0;
102 }
103 #endif
104