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_noinit<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     }
91     {
92         boost::shared_ptr<int[3]> result =
93             boost::allocate_shared_noinit<int[3]>(creator<int>());
94         BOOST_TEST(result.get() != 0);
95         BOOST_TEST(result.use_count() == 1);
96         BOOST_TEST(boost::alignment::is_aligned(result.get(),
97             boost::alignment_of<int>::value));
98     }
99     {
100         boost::shared_ptr<int[][2]> result =
101             boost::allocate_shared_noinit<int[][2]>(creator<>(), 2);
102         BOOST_TEST(result.get() != 0);
103         BOOST_TEST(result.use_count() == 1);
104         BOOST_TEST(boost::alignment::is_aligned(result.get(),
105             boost::alignment_of<int>::value));
106     }
107     {
108         boost::shared_ptr<int[2][2]> result =
109             boost::allocate_shared_noinit<int[2][2]>(creator<>());
110         BOOST_TEST(result.get() != 0);
111         BOOST_TEST(result.use_count() == 1);
112         BOOST_TEST(boost::alignment::is_aligned(result.get(),
113             boost::alignment_of<int>::value));
114     }
115     {
116         boost::shared_ptr<const int[]> result =
117             boost::allocate_shared_noinit<const int[]>(creator<>(), 3);
118         BOOST_TEST(result.get() != 0);
119         BOOST_TEST(result.use_count() == 1);
120         BOOST_TEST(boost::alignment::is_aligned(result.get(),
121             boost::alignment_of<int>::value));
122     }
123     {
124         boost::shared_ptr<const int[3]> result =
125             boost::allocate_shared_noinit<const int[3]>(creator<>());
126         BOOST_TEST(result.get() != 0);
127         BOOST_TEST(result.use_count() == 1);
128         BOOST_TEST(boost::alignment::is_aligned(result.get(),
129             boost::alignment_of<int>::value));
130     }
131     {
132         boost::shared_ptr<const int[][2]> result =
133             boost::allocate_shared_noinit<const int[][2]>(creator<>(), 2);
134         BOOST_TEST(result.get() != 0);
135         BOOST_TEST(result.use_count() == 1);
136         BOOST_TEST(boost::alignment::is_aligned(result.get(),
137             boost::alignment_of<int>::value));
138     }
139     {
140         boost::shared_ptr<const int[2][2]> result =
141             boost::allocate_shared_noinit<const int[2][2]>(creator<>());
142         BOOST_TEST(result.get() != 0);
143         BOOST_TEST(result.use_count() == 1);
144         BOOST_TEST(boost::alignment::is_aligned(result.get(),
145             boost::alignment_of<int>::value));
146     }
147     {
148         boost::shared_ptr<type[]> result =
149             boost::allocate_shared_noinit<type[]>(creator<type>(), 3);
150         BOOST_TEST(result.get() != 0);
151         BOOST_TEST(result.use_count() == 1);
152         BOOST_TEST(boost::alignment::is_aligned(result.get(),
153             boost::alignment_of<type>::value));
154         BOOST_TEST(type::instances == 3);
155         boost::weak_ptr<type[]> other = result;
156         result.reset();
157         BOOST_TEST(type::instances == 0);
158     }
159     {
160         boost::shared_ptr<type[3]> result =
161             boost::allocate_shared_noinit<type[3]>(creator<type>());
162         BOOST_TEST(result.get() != 0);
163         BOOST_TEST(result.use_count() == 1);
164         BOOST_TEST(boost::alignment::is_aligned(result.get(),
165             boost::alignment_of<type>::value));
166         BOOST_TEST(type::instances == 3);
167         boost::weak_ptr<type[3]> other = result;
168         result.reset();
169         BOOST_TEST(type::instances == 0);
170     }
171     {
172         boost::shared_ptr<type[][2]> result =
173             boost::allocate_shared_noinit<type[][2]>(creator<>(), 2);
174         BOOST_TEST(result.get() != 0);
175         BOOST_TEST(result.use_count() == 1);
176         BOOST_TEST(boost::alignment::is_aligned(result.get(),
177             boost::alignment_of<type>::value));
178         BOOST_TEST(type::instances == 4);
179         boost::weak_ptr<type[][2]> other = result;
180         result.reset();
181         BOOST_TEST(type::instances == 0);
182     }
183     {
184         boost::shared_ptr<type[2][2]> result =
185             boost::allocate_shared_noinit<type[2][2]>(creator<>());
186         BOOST_TEST(result.get() != 0);
187         BOOST_TEST(result.use_count() == 1);
188         BOOST_TEST(boost::alignment::is_aligned(result.get(),
189             boost::alignment_of<type>::value));
190         BOOST_TEST(type::instances == 4);
191         boost::weak_ptr<type[2][2]> other = result;
192         result.reset();
193         BOOST_TEST(type::instances == 0);
194     }
195     {
196         boost::shared_ptr<const type[]> result =
197             boost::allocate_shared_noinit<const type[]>(creator<>(), 3);
198         BOOST_TEST(result.get() != 0);
199         BOOST_TEST(result.use_count() == 1);
200         BOOST_TEST(boost::alignment::is_aligned(result.get(),
201             boost::alignment_of<type>::value));
202         BOOST_TEST(type::instances == 3);
203         boost::weak_ptr<const type[]> other = result;
204         result.reset();
205         BOOST_TEST(type::instances == 0);
206     }
207     {
208         boost::shared_ptr<const type[3]> result =
209             boost::allocate_shared_noinit<const type[3]>(creator<>());
210         BOOST_TEST(result.get() != 0);
211         BOOST_TEST(result.use_count() == 1);
212         BOOST_TEST(boost::alignment::is_aligned(result.get(),
213             boost::alignment_of<type>::value));
214         BOOST_TEST(type::instances == 3);
215         boost::weak_ptr<const type[3]> other = result;
216         result.reset();
217         BOOST_TEST(type::instances == 0);
218     }
219     {
220         boost::shared_ptr<const type[][2]> result =
221             boost::allocate_shared_noinit<const
222                 type[][2]>(creator<>(), 2);
223         BOOST_TEST(result.get() != 0);
224         BOOST_TEST(result.use_count() == 1);
225         BOOST_TEST(boost::alignment::is_aligned(result.get(),
226             boost::alignment_of<type>::value));
227         BOOST_TEST(type::instances == 4);
228         boost::weak_ptr<const type[][2]> other = result;
229         result.reset();
230         BOOST_TEST(type::instances == 0);
231     }
232     {
233         boost::shared_ptr<const type[2][2]> result =
234             boost::allocate_shared_noinit<const type[2][2]>(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 == 4);
240         boost::weak_ptr<const type[2][2]> other = result;
241         result.reset();
242         BOOST_TEST(type::instances == 0);
243     }
244     return boost::report_errors();
245 }
246