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/core/lightweight_test.hpp>
9 #include <boost/make_shared.hpp>
10
11 #if !defined(BOOST_NO_CXX11_ALLOCATOR)
12 struct counters {
13 unsigned allocate;
14 unsigned construct;
15 };
16
17 template<class T = void>
18 class creator {
19 public:
20 typedef T value_type;
21
creator(counters * state)22 creator(counters* state)
23 : state_(state) { }
24
25 template<class U>
creator(const creator<U> & other)26 creator(const creator<U>& other)
27 : state_(other.state()) { }
28
allocate(std::size_t size)29 T* allocate(std::size_t size) {
30 void* ptr = ::operator new(sizeof(T) * size);
31 ++state_->allocate;
32 return static_cast<T*>(ptr);
33 }
34
deallocate(T * ptr,std::size_t)35 void deallocate(T* ptr, std::size_t) {
36 ::operator delete(ptr);
37 --state_->allocate;
38 }
39
40 template<class... Args>
construct(T * ptr,Args &&...args)41 void construct(T* ptr, Args&&... args) {
42 ::new(static_cast<void*>(ptr)) T(std::forward<Args>(args)...);
43 ++state_->construct;
44 }
45
destroy(T * ptr)46 void destroy(T* ptr) {
47 ptr->~T();
48 --state_->construct;
49 }
50
state() const51 counters* state() const {
52 return state_;
53 }
54
55 private:
56 counters* state_;
57 };
58
59 template<class T, class U>
60 inline bool
operator ==(const creator<T> & lhs,const creator<U> & rhs)61 operator==(const creator<T>& lhs, const creator<U>& rhs)
62 {
63 return lhs.state() == rhs.state();
64 }
65
66 template<class T, class U>
67 inline bool
operator !=(const creator<T> & lhs,const creator<U> & rhs)68 operator!=(const creator<T>& lhs, const creator<U>& rhs)
69 {
70 return !(lhs == rhs);
71 }
72
73 struct deleter {
74 template<class U>
operator ()deleter75 void operator()(U ptr) const {
76 delete ptr;
77 }
78 };
79
main()80 int main()
81 {
82 {
83 counters state = { };
84 boost::shared_ptr<int> pointer(new int(), deleter(),
85 creator<int>(&state));
86 BOOST_TEST(state.allocate == 1);
87 BOOST_TEST(state.construct == 0);
88 pointer.reset();
89 BOOST_TEST(state.allocate == 0);
90 }
91 {
92 counters state = { };
93 boost::shared_ptr<int> pointer =
94 boost::allocate_shared<int>(creator<int>(&state));
95 BOOST_TEST(state.allocate == 1);
96 BOOST_TEST(state.construct == 1);
97 pointer.reset();
98 BOOST_TEST(state.allocate == 0);
99 BOOST_TEST(state.construct == 0);
100 }
101 {
102 counters state = { };
103 boost::shared_ptr<int[]> pointer =
104 boost::allocate_shared<int[]>(creator<>(&state), 5);
105 BOOST_TEST(state.allocate == 1);
106 BOOST_TEST(state.construct == 5);
107 pointer.reset();
108 BOOST_TEST(state.allocate == 0);
109 BOOST_TEST(state.construct == 0);
110 }
111 {
112 counters state = { };
113 boost::shared_ptr<int[5]> pointer =
114 boost::allocate_shared<int[5]>(creator<>(&state));
115 BOOST_TEST(state.allocate == 1);
116 BOOST_TEST(state.construct == 5);
117 pointer.reset();
118 BOOST_TEST(state.allocate == 0);
119 BOOST_TEST(state.construct == 0);
120 }
121 return boost::report_errors();
122 }
123 #else
main()124 int main()
125 {
126 return 0;
127 }
128 #endif
129