]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /* Copyright (C) 2000, 2001 Stephen Cleary |
2 | * Copyright (C) 2011 Kwan Ting Chan | |
3 | * | |
4 | * Use, modification and distribution is subject to the | |
5 | * Boost Software License, Version 1.0. (See accompanying | |
6 | * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) | |
7 | */ | |
8 | ||
9 | #ifndef BOOST_POOL_TEST_SIMP_SEG_STORE_HPP | |
10 | #define BOOST_POOL_TEST_SIMP_SEG_STORE_HPP | |
11 | ||
12 | #include <boost/pool/simple_segregated_storage.hpp> | |
13 | #include <boost/assert.hpp> | |
14 | ||
15 | #include <boost/detail/lightweight_test.hpp> | |
16 | ||
17 | #include <functional> | |
18 | #include <set> | |
19 | #include <utility> | |
20 | #include <vector> | |
21 | ||
22 | #include <cstddef> | |
23 | ||
24 | class test_simp_seg_store : public boost::simple_segregated_storage<std::size_t> | |
25 | { | |
26 | private: | |
27 | // ::first is the address of the start of the added block, | |
28 | // ::second is the size in bytes of the added block | |
29 | std::vector<std::pair<void*, std::size_t> > allocated_blocks; | |
30 | size_type np_sz; | |
31 | std::set<void*> allocated_chunks; | |
32 | ||
33 | void set_partition_size(const size_type sz) | |
34 | { | |
35 | if(allocated_blocks.empty()) | |
36 | { | |
37 | np_sz = sz; | |
38 | } | |
39 | else | |
40 | { | |
41 | BOOST_ASSERT(np_sz == sz); | |
42 | } | |
43 | } | |
44 | ||
45 | // Return: true if chunk is from added blocks, false otherwise | |
46 | bool is_inside_allocated_blocks(void* const chunk) const | |
47 | { | |
48 | typedef std::vector<std::pair<void*, std::size_t> >::const_iterator | |
49 | VPIter; | |
50 | for(VPIter iter = allocated_blocks.begin(); | |
51 | iter != allocated_blocks.end(); | |
52 | ++iter) | |
53 | { | |
54 | if( std::less_equal<void*>()(iter->first, chunk) | |
55 | && std::less_equal<void*>()(static_cast<char*>(chunk) + np_sz, | |
56 | static_cast<char*>(iter->first) + iter->second) ) | |
57 | { | |
58 | return true; | |
59 | } | |
60 | } | |
61 | ||
62 | return false; | |
63 | } | |
64 | ||
65 | void check_in(void* const chunk) | |
66 | { | |
67 | // Check that the newly allocated chunk has not already previously | |
68 | // been allocated, and that the memory does not overlap with | |
69 | // previously allocated chunks | |
70 | for(std::set<void*>::const_iterator iter = allocated_chunks.begin(); | |
71 | iter != allocated_chunks.end(); | |
72 | ++iter) | |
73 | { | |
74 | BOOST_TEST( std::less_equal<void*>()(static_cast<char*>(chunk) | |
75 | + np_sz, *iter) | |
76 | || std::less_equal<void*>()(static_cast<char*>(*iter) | |
77 | + np_sz, chunk) ); | |
78 | } | |
79 | ||
80 | allocated_chunks.insert(chunk); | |
81 | } | |
82 | ||
83 | void check_out(void* const chunk) | |
84 | { | |
85 | BOOST_TEST(allocated_chunks.erase(chunk) == 1); | |
86 | } | |
87 | ||
88 | public: | |
89 | test_simp_seg_store() | |
90 | : np_sz(0) {} | |
91 | ||
92 | void* get_first() { return first; } | |
93 | static void*& get_nextof(void* const ptr) { return nextof(ptr); } | |
94 | ||
95 | // (Test) Pre: npartition_sz of all added block is the same | |
96 | // different blocks of memory does not overlap | |
97 | void add_block(void* const block, | |
98 | const size_type nsz, const size_type npartition_sz) | |
99 | { | |
100 | set_partition_size(npartition_sz); | |
101 | allocated_blocks.push_back( | |
102 | std::pair<void*, std::size_t>(block, nsz) ); | |
103 | boost::simple_segregated_storage<std::size_t>::add_block( | |
104 | block, nsz, npartition_sz ); | |
105 | // Post: !empty() | |
106 | BOOST_TEST(!empty()); | |
107 | } | |
108 | ||
109 | // (Test) Pre: npartition_sz of all added block is the same | |
110 | // different blocks of memory does not overlap | |
111 | void add_ordered_block(void* const block, | |
112 | const size_type nsz, const size_type npartition_sz) | |
113 | { | |
114 | set_partition_size(npartition_sz); | |
115 | allocated_blocks.push_back( | |
116 | std::pair<void*, std::size_t>(block, nsz) ); | |
117 | boost::simple_segregated_storage<std::size_t>::add_ordered_block( | |
118 | block, nsz, npartition_sz ); | |
119 | // Post: !empty() | |
120 | BOOST_TEST(!empty()); | |
121 | } | |
122 | ||
123 | void* malloc() | |
124 | { | |
125 | void* const ret | |
126 | = boost::simple_segregated_storage<std::size_t>::malloc(); | |
127 | // Chunk returned should actually be from added blocks | |
128 | BOOST_TEST(is_inside_allocated_blocks(ret)); | |
129 | check_in(ret); | |
130 | return ret; | |
131 | } | |
132 | ||
133 | void free(void* const chunk) | |
134 | { | |
135 | BOOST_ASSERT(chunk); | |
136 | check_out(chunk); | |
137 | boost::simple_segregated_storage<std::size_t>::free(chunk); | |
138 | // Post: !empty() | |
139 | BOOST_TEST(!empty()); | |
140 | } | |
141 | ||
142 | void ordered_free(void* const chunk) | |
143 | { | |
144 | BOOST_ASSERT(chunk); | |
145 | check_out(chunk); | |
146 | boost::simple_segregated_storage<std::size_t>::ordered_free(chunk); | |
147 | // Post: !empty() | |
148 | BOOST_TEST(!empty()); | |
149 | } | |
150 | ||
151 | void* malloc_n(size_type n, size_type partition_size) | |
152 | { | |
153 | void* const ret | |
154 | = boost::simple_segregated_storage<std::size_t>::malloc_n( | |
155 | n, partition_size ); | |
156 | ||
157 | if(ret) | |
158 | { | |
159 | for(std::size_t i=0; i < n; ++i) | |
160 | { | |
161 | void* const chunk = static_cast<char*>(ret) | |
162 | + (i * partition_size); | |
163 | // Memory returned should actually be from added blocks | |
164 | BOOST_TEST(is_inside_allocated_blocks(chunk)); | |
165 | check_in(chunk); | |
166 | } | |
167 | } | |
168 | ||
169 | return ret; | |
170 | } | |
171 | }; | |
172 | ||
173 | #endif // BOOST_POOL_TEST_SIMP_SEG_STORE_HPP |