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