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     !defined(BOOST_NO_CXX11_ALLOCATOR)
12 #include <boost/core/lightweight_test.hpp>
13 #include <boost/smart_ptr/make_local_shared.hpp>
14 
15 struct allow { };
16 
17 template<class T = void>
18 struct creator {
19     typedef T value_type;
20 
21     template<class U>
22     struct rebind {
23         typedef creator<U> other;
24     };
25 
creatorcreator26     creator() { }
27 
28     template<class U>
creatorcreator29     creator(const creator<U>&) { }
30 
allocatecreator31     T* allocate(std::size_t size) {
32         return static_cast<T*>(::operator new(sizeof(T) * size));
33     }
34 
deallocatecreator35     void deallocate(T* ptr, std::size_t) {
36         ::operator delete(ptr);
37     }
38 
39     template<class U>
constructcreator40     void construct(U* ptr) {
41         ::new(static_cast<void*>(ptr)) U(allow());
42     }
43 
44     template<class U>
destroycreator45     void destroy(U* ptr) {
46         ptr->~U();
47     }
48 
49 };
50 
51 template<class T, class U>
52 inline bool
operator ==(const creator<T> &,const creator<U> &)53 operator==(const creator<T>&, const creator<U>&)
54 {
55     return true;
56 }
57 
58 template<class T, class U>
59 inline bool
operator !=(const creator<T> &,const creator<U> &)60 operator!=(const creator<T>&, const creator<U>&)
61 {
62     return false;
63 }
64 
65 class type {
66 public:
67     static unsigned instances;
68 
type(allow)69     explicit type(allow) {
70         ++instances;
71     }
72 
~type()73     ~type() {
74         --instances;
75     }
76 
77 private:
78     type(const type&);
79     type& operator=(const type&);
80 };
81 
82 unsigned type::instances = 0;
83 
main()84 int main()
85 {
86     {
87         boost::local_shared_ptr<type[]> result =
88             boost::allocate_local_shared<type[]>(creator<type>(), 3);
89         BOOST_TEST(result.get() != 0);
90         BOOST_TEST(result.local_use_count() == 1);
91         BOOST_TEST(type::instances == 3);
92         result.reset();
93         BOOST_TEST(type::instances == 0);
94     }
95     {
96         boost::local_shared_ptr<type[3]> result =
97             boost::allocate_local_shared<type[3]>(creator<type>());
98         BOOST_TEST(result.get() != 0);
99         BOOST_TEST(result.local_use_count() == 1);
100         BOOST_TEST(type::instances == 3);
101         result.reset();
102         BOOST_TEST(type::instances == 0);
103     }
104     {
105         boost::local_shared_ptr<type[][2]> result =
106             boost::allocate_local_shared<type[][2]>(creator<>(), 2);
107         BOOST_TEST(result.get() != 0);
108         BOOST_TEST(result.local_use_count() == 1);
109         BOOST_TEST(type::instances == 4);
110         result.reset();
111         BOOST_TEST(type::instances == 0);
112     }
113     {
114         boost::local_shared_ptr<type[2][2]> result =
115             boost::allocate_local_shared<type[2][2]>(creator<>());
116         BOOST_TEST(result.get() != 0);
117         BOOST_TEST(result.local_use_count() == 1);
118         BOOST_TEST(type::instances == 4);
119         result.reset();
120         BOOST_TEST(type::instances == 0);
121     }
122     {
123         boost::local_shared_ptr<const type[]> result =
124             boost::allocate_local_shared<const type[]>(creator<>(), 3);
125         BOOST_TEST(result.get() != 0);
126         BOOST_TEST(result.local_use_count() == 1);
127         BOOST_TEST(type::instances == 3);
128         result.reset();
129         BOOST_TEST(type::instances == 0);
130     }
131     {
132         boost::local_shared_ptr<const type[3]> result =
133             boost::allocate_local_shared<const type[3]>(creator<>());
134         BOOST_TEST(result.get() != 0);
135         BOOST_TEST(result.local_use_count() == 1);
136         BOOST_TEST(type::instances == 3);
137         result.reset();
138         BOOST_TEST(type::instances == 0);
139     }
140     {
141         boost::local_shared_ptr<const type[][2]> result =
142             boost::allocate_local_shared<const type[][2]>(creator<>(), 2);
143         BOOST_TEST(result.get() != 0);
144         BOOST_TEST(result.local_use_count() == 1);
145         BOOST_TEST(type::instances == 4);
146         result.reset();
147         BOOST_TEST(type::instances == 0);
148     }
149     {
150         boost::local_shared_ptr<const type[2][2]> result =
151             boost::allocate_local_shared<const type[2][2]>(creator<>());
152         BOOST_TEST(result.get() != 0);
153         BOOST_TEST(result.local_use_count() == 1);
154         BOOST_TEST(type::instances == 4);
155         result.reset();
156         BOOST_TEST(type::instances == 0);
157     }
158     return boost::report_errors();
159 }
160 #else
main()161 int main()
162 {
163     return 0;
164 }
165 #endif
166