1 | /* |
2 | Copyright 2019 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_LIBSTDCXX_VERSION) || \ |
10 | BOOST_LIBSTDCXX_VERSION >= 48000) && \ |
11 | !defined(BOOST_NO_CXX11_SMART_PTR) |
12 | #include <boost/smart_ptr/allocate_unique.hpp> |
13 | #include <boost/core/lightweight_test.hpp> |
14 | |
15 | template<class T = void> |
16 | struct creator { |
17 | typedef T value_type; |
18 | typedef T* pointer; |
19 | |
20 | template<class U> |
21 | struct rebind { |
22 | typedef creator<U> other; |
23 | }; |
24 | |
25 | creator() { } |
26 | |
27 | template<class U> |
28 | creator(const creator<U>&) { } |
29 | |
30 | T* allocate(std::size_t size) { |
31 | return static_cast<T*>(::operator new(sizeof(T) * size)); |
32 | } |
33 | |
34 | void deallocate(T* ptr, std::size_t) { |
35 | ::operator delete(ptr); |
36 | } |
37 | }; |
38 | |
39 | template<class T, class U> |
40 | inline bool |
41 | operator==(const creator<T>&, const creator<U>&) |
42 | { |
43 | return true; |
44 | } |
45 | |
46 | template<class T, class U> |
47 | inline bool |
48 | operator!=(const creator<T>&, const creator<U>&) |
49 | { |
50 | return false; |
51 | } |
52 | |
53 | class type { |
54 | public: |
55 | static unsigned instances; |
56 | |
57 | type() { |
58 | if (instances == 5) { |
59 | throw true; |
60 | } |
61 | ++instances; |
62 | } |
63 | |
64 | ~type() { |
65 | --instances; |
66 | } |
67 | |
68 | private: |
69 | type(const type&); |
70 | type& operator=(const type&); |
71 | }; |
72 | |
73 | unsigned type::instances = 0; |
74 | |
75 | int main() |
76 | { |
77 | try { |
78 | boost::allocate_unique<type[]>(alloc: creator<type>(), size: 6); |
79 | BOOST_ERROR("allocate_unique did not throw" ); |
80 | } catch (...) { |
81 | BOOST_TEST(type::instances == 0); |
82 | } |
83 | try { |
84 | boost::allocate_unique<type[][2]>(alloc: creator<type>(), size: 3); |
85 | BOOST_ERROR("allocate_unique did not throw" ); |
86 | } catch (...) { |
87 | BOOST_TEST(type::instances == 0); |
88 | } |
89 | try { |
90 | boost::allocate_unique<type[6]>(alloc: creator<>()); |
91 | BOOST_ERROR("allocate_unique did not throw" ); |
92 | } catch (...) { |
93 | BOOST_TEST(type::instances == 0); |
94 | } |
95 | try { |
96 | boost::allocate_unique<type[3][2]>(alloc: creator<>()); |
97 | BOOST_ERROR("allocate_unique did not throw" ); |
98 | } catch (...) { |
99 | BOOST_TEST(type::instances == 0); |
100 | } |
101 | try { |
102 | boost::allocate_unique_noinit<type[]>(alloc: creator<>(), size: 6); |
103 | BOOST_ERROR("allocate_unique_noinit did not throw" ); |
104 | } catch (...) { |
105 | BOOST_TEST(type::instances == 0); |
106 | } |
107 | try { |
108 | boost::allocate_unique_noinit<type[][2]>(alloc: creator<>(), size: 3); |
109 | BOOST_ERROR("allocate_unique_noinit did not throw" ); |
110 | } catch (...) { |
111 | BOOST_TEST(type::instances == 0); |
112 | } |
113 | try { |
114 | boost::allocate_unique_noinit<type[6]>(alloc: creator<>()); |
115 | BOOST_ERROR("allocate_unique_noinit did not throw" ); |
116 | } catch (...) { |
117 | BOOST_TEST(type::instances == 0); |
118 | } |
119 | try { |
120 | boost::allocate_unique_noinit<type[3][2]>(alloc: creator<>()); |
121 | BOOST_ERROR("allocate_unique_noinit did not throw" ); |
122 | } catch (...) { |
123 | BOOST_TEST(type::instances == 0); |
124 | } |
125 | return boost::report_errors(); |
126 | } |
127 | #else |
128 | int main() |
129 | { |
130 | return 0; |
131 | } |
132 | #endif |
133 | |