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