• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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