| 1 | //////////////////////////////////////// |
| 2 | // |
| 3 | // (C) Copyright Ion Gaztanaga 2006-2012. Distributed under the Boost |
| 4 | // Software License, Version 1.0. (See accompanying file |
| 5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 6 | // |
| 7 | // See http://www.boost.org/libs/interprocess for documentation. |
| 8 | // |
| 9 | //////////////////////////////////////// |
| 10 | |
| 11 | #ifndef BOOST_INTERPROCESS_TEST_LIST_TEST_HEADER |
| 12 | #define |
| 13 | |
| 14 | #include <boost/interprocess/detail/config_begin.hpp> |
| 15 | #include "check_equal_containers.hpp" |
| 16 | #include <memory> |
| 17 | #include <list> |
| 18 | #include <vector> |
| 19 | #include <functional> |
| 20 | #include "print_container.hpp" |
| 21 | #include <boost/move/utility_core.hpp> |
| 22 | #include <string> |
| 23 | #include "get_process_id_name.hpp" |
| 24 | |
| 25 | namespace boost{ |
| 26 | namespace interprocess{ |
| 27 | namespace test{ |
| 28 | |
| 29 | template<bool DoublyLinked> |
| 30 | struct push_data_function |
| 31 | { |
| 32 | template<class MyShmList, class MyStdList> |
| 33 | static int execute(int max, MyShmList *shmlist, MyStdList *stdlist) |
| 34 | { |
| 35 | typedef typename MyShmList::value_type IntType; |
| 36 | for(int i = 0; i < max; ++i){ |
| 37 | IntType move_me(i); |
| 38 | shmlist->push_back(boost::move(move_me)); |
| 39 | stdlist->push_back(i); |
| 40 | shmlist->push_back(IntType(i)); |
| 41 | stdlist->push_back(int(i)); |
| 42 | } |
| 43 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 44 | return 1; |
| 45 | return 0; |
| 46 | } |
| 47 | }; |
| 48 | |
| 49 | template<> |
| 50 | struct push_data_function<false> |
| 51 | { |
| 52 | template<class MyShmList, class MyStdList> |
| 53 | static int execute(int max, MyShmList *shmlist, MyStdList *stdlist) |
| 54 | { |
| 55 | typedef typename MyShmList::value_type IntType; |
| 56 | for(int i = 0; i < max; ++i){ |
| 57 | IntType move_me(i); |
| 58 | shmlist->push_front(boost::move(move_me)); |
| 59 | stdlist->push_front(i); |
| 60 | shmlist->push_front(IntType(i)); |
| 61 | stdlist->push_front(int(i)); |
| 62 | } |
| 63 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 64 | return 1; |
| 65 | return 0; |
| 66 | } |
| 67 | }; |
| 68 | |
| 69 | template<bool DoublyLinked> |
| 70 | struct pop_back_function |
| 71 | { |
| 72 | template<class MyStdList, class MyShmList> |
| 73 | static int execute(MyShmList *shmlist, MyStdList *stdlist) |
| 74 | { |
| 75 | shmlist->pop_back(); |
| 76 | stdlist->pop_back(); |
| 77 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 78 | return 1; |
| 79 | return 0; |
| 80 | } |
| 81 | }; |
| 82 | |
| 83 | template<> |
| 84 | struct pop_back_function<false> |
| 85 | { |
| 86 | template<class MyStdList, class MyShmList> |
| 87 | static int execute(MyShmList *shmlist, MyStdList *stdlist) |
| 88 | { |
| 89 | (void)shmlist; (void)stdlist; |
| 90 | return 0; |
| 91 | } |
| 92 | }; |
| 93 | |
| 94 | template<class ManagedSharedMemory |
| 95 | ,class MyShmList |
| 96 | ,bool DoublyLinked> |
| 97 | int list_test (bool copied_allocators_equal = true) |
| 98 | { |
| 99 | typedef std::list<int> MyStdList; |
| 100 | typedef typename MyShmList::value_type IntType; |
| 101 | const int Memsize = 128u * 1024u; |
| 102 | const char *const shMemName = test::get_process_id_name(); |
| 103 | const int max = 100; |
| 104 | typedef push_data_function<DoublyLinked> push_data_t; |
| 105 | |
| 106 | BOOST_TRY{ |
| 107 | //Named new capable shared mem allocator |
| 108 | //Create shared memory |
| 109 | shared_memory_object::remove(filename: shMemName); |
| 110 | ManagedSharedMemory segment(create_only, shMemName, Memsize); |
| 111 | |
| 112 | segment.reserve_named_objects(10); |
| 113 | |
| 114 | //Shared memory allocator must be always be initialized |
| 115 | //since it has no default constructor |
| 116 | MyShmList *shmlist = segment.template construct<MyShmList>("MyList" ) |
| 117 | (segment.get_segment_manager()); |
| 118 | |
| 119 | |
| 120 | MyStdList *stdlist = new MyStdList; |
| 121 | |
| 122 | if(push_data_t::execute(max/2, shmlist, stdlist)){ |
| 123 | return 1; |
| 124 | } |
| 125 | |
| 126 | shmlist->erase(shmlist->begin()++); |
| 127 | stdlist->erase(position: stdlist->begin()++); |
| 128 | if(!CheckEqualContainers(shmlist, stdlist)) return 1; |
| 129 | |
| 130 | if(pop_back_function<DoublyLinked>::execute(shmlist, stdlist)){ |
| 131 | return 1; |
| 132 | } |
| 133 | |
| 134 | shmlist->pop_front(); |
| 135 | stdlist->pop_front(); |
| 136 | if(!CheckEqualContainers(shmlist, stdlist)) return 1; |
| 137 | |
| 138 | { |
| 139 | IntType aux_vect[50]; |
| 140 | for(int i = 0; i < 50; ++i){ |
| 141 | IntType move_me(-1); |
| 142 | aux_vect[i] = boost::move(move_me); |
| 143 | } |
| 144 | int aux_vect2[50]; |
| 145 | for(int i = 0; i < 50; ++i){ |
| 146 | aux_vect2[i] = -1; |
| 147 | } |
| 148 | shmlist->assign(::boost::make_move_iterator(&aux_vect[0]) |
| 149 | ,::boost::make_move_iterator(&aux_vect[50])); |
| 150 | stdlist->assign(first: &aux_vect2[0], last: &aux_vect2[50]); |
| 151 | if(!CheckEqualContainers(shmlist, stdlist)) return 1; |
| 152 | } |
| 153 | |
| 154 | if(copied_allocators_equal){ |
| 155 | shmlist->sort(); |
| 156 | stdlist->sort(); |
| 157 | if(!CheckEqualContainers(shmlist, stdlist)) return 1; |
| 158 | } |
| 159 | |
| 160 | shmlist->reverse(); |
| 161 | stdlist->reverse(); |
| 162 | if(!CheckEqualContainers(shmlist, stdlist)) return 1; |
| 163 | |
| 164 | shmlist->reverse(); |
| 165 | stdlist->reverse(); |
| 166 | if(!CheckEqualContainers(shmlist, stdlist)) return 1; |
| 167 | |
| 168 | { |
| 169 | IntType aux_vect[50]; |
| 170 | for(int i = 0; i < 50; ++i){ |
| 171 | IntType move_me(-1); |
| 172 | aux_vect[i] = boost::move(move_me); |
| 173 | } |
| 174 | int aux_vect2[50]; |
| 175 | for(int i = 0; i < 50; ++i){ |
| 176 | aux_vect2[i] = -1; |
| 177 | } |
| 178 | shmlist->insert(shmlist->begin() |
| 179 | ,::boost::make_move_iterator(&aux_vect[0]) |
| 180 | ,::boost::make_move_iterator(&aux_vect[50])); |
| 181 | stdlist->insert(position: stdlist->begin(), first: &aux_vect2[0], last: &aux_vect2[50]); |
| 182 | } |
| 183 | |
| 184 | shmlist->unique(); |
| 185 | stdlist->unique(); |
| 186 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 187 | return 1; |
| 188 | |
| 189 | if(copied_allocators_equal){ |
| 190 | shmlist->sort(std::greater<IntType>()); |
| 191 | stdlist->sort(comp: std::greater<int>()); |
| 192 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 193 | return 1; |
| 194 | } |
| 195 | |
| 196 | shmlist->resize(25); |
| 197 | stdlist->resize(new_size: 25); |
| 198 | shmlist->resize(50); |
| 199 | stdlist->resize(new_size: 50); |
| 200 | shmlist->resize(0); |
| 201 | stdlist->resize(new_size: 0); |
| 202 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 203 | return 1; |
| 204 | |
| 205 | if(push_data_t::execute(max/2, shmlist, stdlist)){ |
| 206 | return 1; |
| 207 | } |
| 208 | { |
| 209 | MyShmList othershmlist(shmlist->get_allocator()); |
| 210 | MyStdList otherstdlist; |
| 211 | |
| 212 | int listsize = (int)shmlist->size(); |
| 213 | |
| 214 | if(push_data_t::execute(listsize/2, shmlist, stdlist)){ |
| 215 | return 1; |
| 216 | } |
| 217 | |
| 218 | if(copied_allocators_equal){ |
| 219 | shmlist->splice(shmlist->begin(), othershmlist); |
| 220 | stdlist->splice(position: stdlist->begin(), x&: otherstdlist); |
| 221 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 222 | return 1; |
| 223 | } |
| 224 | |
| 225 | listsize = (int)shmlist->size(); |
| 226 | |
| 227 | if(push_data_t::execute(listsize/2, shmlist, stdlist)){ |
| 228 | return 1; |
| 229 | } |
| 230 | |
| 231 | if(push_data_t::execute(listsize/2, &othershmlist, &otherstdlist)){ |
| 232 | return 1; |
| 233 | } |
| 234 | |
| 235 | if(copied_allocators_equal){ |
| 236 | shmlist->sort(std::greater<IntType>()); |
| 237 | stdlist->sort(comp: std::greater<int>()); |
| 238 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 239 | return 1; |
| 240 | |
| 241 | othershmlist.sort(std::greater<IntType>()); |
| 242 | otherstdlist.sort(comp: std::greater<int>()); |
| 243 | if(!CheckEqualContainers(&othershmlist, &otherstdlist)) |
| 244 | return 1; |
| 245 | |
| 246 | shmlist->merge(othershmlist, std::greater<IntType>()); |
| 247 | stdlist->merge(x&: otherstdlist, comp: std::greater<int>()); |
| 248 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 249 | return 1; |
| 250 | } |
| 251 | |
| 252 | for(int i = 0; i < max; ++i){ |
| 253 | shmlist->insert(shmlist->begin(), IntType(i)); |
| 254 | stdlist->insert(position: stdlist->begin(), x: int(i)); |
| 255 | } |
| 256 | if(!CheckEqualContainers(shmlist, stdlist)) |
| 257 | return 1; |
| 258 | } |
| 259 | |
| 260 | segment.template destroy<MyShmList>("MyList" ); |
| 261 | delete stdlist; |
| 262 | segment.shrink_to_fit_indexes(); |
| 263 | |
| 264 | if(!segment.all_memory_deallocated()) |
| 265 | return 1; |
| 266 | } |
| 267 | BOOST_CATCH(...){ |
| 268 | shared_memory_object::remove(filename: shMemName); |
| 269 | BOOST_RETHROW |
| 270 | } BOOST_CATCH_END |
| 271 | shared_memory_object::remove(filename: shMemName); |
| 272 | return 0; |
| 273 | } |
| 274 | |
| 275 | } //namespace test{ |
| 276 | } //namespace interprocess{ |
| 277 | } //namespace boost{ |
| 278 | |
| 279 | #include <boost/interprocess/detail/config_end.hpp> |
| 280 | |
| 281 | #endif |
| 282 | |