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/align/is_aligned.hpp>
12 #include <boost/core/lightweight_test.hpp>
13 #include <boost/smart_ptr/make_local_shared.hpp>
14 #include <boost/smart_ptr/weak_ptr.hpp>
15 #include <boost/type_traits/alignment_of.hpp>
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 
40 template<class T, class U>
41 inline bool
operator ==(const creator<T> &,const creator<U> &)42 operator==(const creator<T>&, const creator<U>&)
43 {
44     return true;
45 }
46 
47 template<class T, class U>
48 inline bool
operator !=(const creator<T> &,const creator<U> &)49 operator!=(const creator<T>&, const creator<U>&)
50 {
51     return false;
52 }
53 
54 class type {
55 public:
56     static unsigned instances;
57 
type()58     type()
59         : value_(0.0) {
60         ++instances;
61     }
62 
~type()63     ~type() {
64         --instances;
65     }
66 
set(long double value)67     void set(long double value) {
68         value_ = value;
69     }
70 
get() const71     long double get() const {
72         return value_;
73     }
74 
75 private:
76     type(const type&);
77     type& operator=(const type&);
78 
79     long double value_;
80 };
81 
82 unsigned type::instances = 0;
83 
main()84 int main()
85 {
86     {
87         boost::local_shared_ptr<int[]> result =
88             boost::allocate_local_shared<int[]>(creator<int>(), 3);
89         BOOST_TEST(result.get() != 0);
90         BOOST_TEST(result.local_use_count() == 1);
91         BOOST_TEST(boost::alignment::is_aligned(result.get(),
92             boost::alignment_of<int>::value));
93         BOOST_TEST(result[0] == 0);
94         BOOST_TEST(result[1] == 0);
95         BOOST_TEST(result[2] == 0);
96     }
97     {
98         boost::local_shared_ptr<int[3]> result =
99             boost::allocate_local_shared<int[3]>(creator<int>());
100         BOOST_TEST(result.get() != 0);
101         BOOST_TEST(result.local_use_count() == 1);
102         BOOST_TEST(boost::alignment::is_aligned(result.get(),
103             boost::alignment_of<int>::value));
104         BOOST_TEST(result[0] == 0);
105         BOOST_TEST(result[1] == 0);
106         BOOST_TEST(result[2] == 0);
107     }
108     {
109         boost::local_shared_ptr<int[][2]> result =
110             boost::allocate_local_shared<int[][2]>(creator<>(), 2);
111         BOOST_TEST(result.get() != 0);
112         BOOST_TEST(result.local_use_count() == 1);
113         BOOST_TEST(boost::alignment::is_aligned(result.get(),
114             boost::alignment_of<int>::value));
115         BOOST_TEST(result[0][0] == 0);
116         BOOST_TEST(result[0][1] == 0);
117         BOOST_TEST(result[1][0] == 0);
118         BOOST_TEST(result[1][1] == 0);
119     }
120     {
121         boost::local_shared_ptr<int[2][2]> result =
122             boost::allocate_local_shared<int[2][2]>(creator<>());
123         BOOST_TEST(result.get() != 0);
124         BOOST_TEST(result.local_use_count() == 1);
125         BOOST_TEST(boost::alignment::is_aligned(result.get(),
126             boost::alignment_of<int>::value));
127         BOOST_TEST(result[0][0] == 0);
128         BOOST_TEST(result[0][1] == 0);
129         BOOST_TEST(result[1][0] == 0);
130         BOOST_TEST(result[1][1] == 0);
131     }
132     {
133         boost::local_shared_ptr<const int[]> result =
134             boost::allocate_local_shared<const int[]>(creator<>(), 3);
135         BOOST_TEST(result.get() != 0);
136         BOOST_TEST(result.local_use_count() == 1);
137         BOOST_TEST(boost::alignment::is_aligned(result.get(),
138             boost::alignment_of<int>::value));
139         BOOST_TEST(result[0] == 0);
140         BOOST_TEST(result[1] == 0);
141         BOOST_TEST(result[2] == 0);
142     }
143     {
144         boost::local_shared_ptr<const int[3]> result =
145             boost::allocate_local_shared<const int[3]>(creator<>());
146         BOOST_TEST(result.get() != 0);
147         BOOST_TEST(result.local_use_count() == 1);
148         BOOST_TEST(boost::alignment::is_aligned(result.get(),
149             boost::alignment_of<int>::value));
150         BOOST_TEST(result[0] == 0);
151         BOOST_TEST(result[1] == 0);
152         BOOST_TEST(result[2] == 0);
153     }
154     {
155         boost::local_shared_ptr<const int[][2]> result =
156             boost::allocate_local_shared<const int[][2]>(creator<>(), 2);
157         BOOST_TEST(result.get() != 0);
158         BOOST_TEST(result.local_use_count() == 1);
159         BOOST_TEST(boost::alignment::is_aligned(result.get(),
160             boost::alignment_of<int>::value));
161         BOOST_TEST(result[0][0] == 0);
162         BOOST_TEST(result[0][1] == 0);
163         BOOST_TEST(result[1][0] == 0);
164         BOOST_TEST(result[1][1] == 0);
165     }
166     {
167         boost::local_shared_ptr<const int[2][2]> result =
168             boost::allocate_local_shared<const int[2][2]>(creator<>());
169         BOOST_TEST(result.get() != 0);
170         BOOST_TEST(result.local_use_count() == 1);
171         BOOST_TEST(boost::alignment::is_aligned(result.get(),
172             boost::alignment_of<int>::value));
173         BOOST_TEST(result[0][0] == 0);
174         BOOST_TEST(result[0][1] == 0);
175         BOOST_TEST(result[1][0] == 0);
176         BOOST_TEST(result[1][1] == 0);
177     }
178     {
179         boost::local_shared_ptr<type[]> result =
180             boost::allocate_local_shared<type[]>(creator<type>(), 3);
181         BOOST_TEST(result.get() != 0);
182         BOOST_TEST(result.local_use_count() == 1);
183         BOOST_TEST(boost::alignment::is_aligned(result.get(),
184             boost::alignment_of<type>::value));
185         BOOST_TEST(type::instances == 3);
186         boost::weak_ptr<type[]> w1 = result;
187         result.reset();
188         BOOST_TEST(type::instances == 0);
189     }
190     {
191         boost::local_shared_ptr<type[3]> result =
192             boost::allocate_local_shared<type[3]>(creator<type>());
193         BOOST_TEST(result.get() != 0);
194         BOOST_TEST(result.local_use_count() == 1);
195         BOOST_TEST(boost::alignment::is_aligned(result.get(),
196             boost::alignment_of<type>::value));
197         BOOST_TEST(type::instances == 3);
198         boost::weak_ptr<type[3]> w1 = result;
199         result.reset();
200         BOOST_TEST(type::instances == 0);
201     }
202     {
203         boost::local_shared_ptr<type[][2]> result =
204             boost::allocate_local_shared<type[][2]>(creator<>(), 2);
205         BOOST_TEST(result.get() != 0);
206         BOOST_TEST(result.local_use_count() == 1);
207         BOOST_TEST(boost::alignment::is_aligned(result.get(),
208             boost::alignment_of<type>::value));
209         BOOST_TEST(type::instances == 4);
210         result.reset();
211         BOOST_TEST(type::instances == 0);
212     }
213     {
214         boost::local_shared_ptr<type[2][2]> result =
215             boost::allocate_local_shared<type[2][2]>(creator<>());
216         BOOST_TEST(result.get() != 0);
217         BOOST_TEST(result.local_use_count() == 1);
218         BOOST_TEST(boost::alignment::is_aligned(result.get(),
219             boost::alignment_of<type>::value));
220         BOOST_TEST(type::instances == 4);
221         result.reset();
222         BOOST_TEST(type::instances == 0);
223     }
224     {
225         boost::local_shared_ptr<const type[]> result =
226             boost::allocate_local_shared<const type[]>(creator<>(), 3);
227         BOOST_TEST(result.get() != 0);
228         BOOST_TEST(result.local_use_count() == 1);
229         BOOST_TEST(boost::alignment::is_aligned(result.get(),
230             boost::alignment_of<type>::value));
231         BOOST_TEST(type::instances == 3);
232         result.reset();
233         BOOST_TEST(type::instances == 0);
234     }
235     {
236         boost::local_shared_ptr<const type[3]> result =
237             boost::allocate_local_shared<const type[3]>(creator<>());
238         BOOST_TEST(result.get() != 0);
239         BOOST_TEST(result.local_use_count() == 1);
240         BOOST_TEST(boost::alignment::is_aligned(result.get(),
241             boost::alignment_of<type>::value));
242         BOOST_TEST(type::instances == 3);
243         result.reset();
244         BOOST_TEST(type::instances == 0);
245     }
246     {
247         boost::local_shared_ptr<const type[][2]> result =
248             boost::allocate_local_shared<const type[][2]>(creator<>(), 2);
249         BOOST_TEST(result.get() != 0);
250         BOOST_TEST(result.local_use_count() == 1);
251         BOOST_TEST(boost::alignment::is_aligned(result.get(),
252             boost::alignment_of<type>::value));
253         BOOST_TEST(type::instances == 4);
254         result.reset();
255         BOOST_TEST(type::instances == 0);
256     }
257     {
258         boost::local_shared_ptr<const type[2][2]> result =
259             boost::allocate_local_shared<const type[2][2]>(creator<>());
260         BOOST_TEST(result.get() != 0);
261         BOOST_TEST(result.local_use_count() == 1);
262         BOOST_TEST(boost::alignment::is_aligned(result.get(),
263             boost::alignment_of<type>::value));
264         BOOST_TEST(type::instances == 4);
265         result.reset();
266         BOOST_TEST(type::instances == 0);
267     }
268     return boost::report_errors();
269 }
270 #else
main()271 int main()
272 {
273     return 0;
274 }
275 #endif
276