allocators.hpp
Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */ 00002 /* 00003 * Main authors: 00004 * Filip Konvicka <filip.konvicka@logis.cz> 00005 * 00006 * Copyright: 00007 * LOGIS, s.r.o., 2009 00008 * 00009 * Bugfixes provided by: 00010 * Gustavo Gutierrez 00011 * 00012 * Last modified: 00013 * $Date: 2010-05-15 16:21:08 +0200 (Sat, 15 May 2010) $ by $Author: schulte $ 00014 * $Revision: 10955 $ 00015 * 00016 * Permission is hereby granted, free of charge, to any person obtaining 00017 * a copy of this software and associated documentation files (the 00018 * "Software"), to deal in the Software without restriction, including 00019 * without limitation the rights to use, copy, modify, merge, publish, 00020 * distribute, sublicense, and/or sell copies of the Software, and to 00021 * permit persons to whom the Software is furnished to do so, subject to 00022 * the following conditions: 00023 * 00024 * The above copyright notice and this permission notice shall be 00025 * included in all copies or substantial portions of the Software. 00026 * 00027 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 00028 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00029 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00030 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 00031 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 00032 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 00033 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00034 */ 00035 00036 #include <limits> 00037 00038 namespace Gecode { 00039 00040 template<class T> struct space_allocator; 00041 00156 template<> 00157 struct space_allocator<void> { 00158 typedef void* pointer; 00159 typedef const void* const_pointer; 00160 typedef void value_type; 00162 template<class U> struct rebind { 00163 typedef space_allocator<U> other; 00164 }; 00165 }; 00166 00176 template<class T> 00177 struct space_allocator { 00179 typedef T value_type; 00181 typedef size_t size_type; 00183 typedef ptrdiff_t difference_type; 00185 typedef T* pointer; 00187 typedef T const* const_pointer; 00189 typedef T& reference; 00191 typedef T const& const_reference; 00193 template<class U> struct rebind { 00195 typedef space_allocator<U> other; 00196 }; 00197 00199 Space& space; 00200 00205 space_allocator(Space& space) throw() : space(space) {} 00210 space_allocator(space_allocator const& al) throw() : space(al.space) {} 00215 space_allocator& operator =(space_allocator const& al) { 00216 assert(&space == &al.space); 00217 return *this; 00218 } 00223 template<class U> 00224 space_allocator(space_allocator<U> const& al) throw() : space(al.space) {} 00225 00227 pointer address(reference x) const { return &x; } 00229 const_pointer address(const_reference x) const { return &x; } 00231 size_type max_size() const throw() { 00232 return std::numeric_limits<size_type>::max() / 00233 (sizeof(T)>0 ? sizeof(T) : 1); 00234 } 00243 pointer allocate(size_type count) { 00244 return static_cast<pointer>(space.ralloc(sizeof(T)*count)); 00245 } 00246 00257 pointer allocate(size_type count, const void * const hint) { 00258 (void) hint; 00259 return allocate(count); 00260 } 00261 00263 void deallocate(pointer p, size_type count) { 00264 space.rfree(static_cast<void*>(p), count); 00265 } 00266 00267 /* 00268 * \brief Constructs an object 00269 * 00270 * Constructs an object of type \a T with the initial value of \a t 00271 * at the location specified by \a element. This function calls 00272 * the <i>placement new()</i> operator. 00273 */ 00274 void construct(pointer element, const_reference t) { 00275 new (element) T(t); 00276 } 00277 00279 void destroy(pointer element) { 00280 element->~T(); 00281 } 00282 }; 00283 00290 template<class T1, class T2> 00291 bool operator==(space_allocator<T1> const& al1, 00292 space_allocator<T2> const& al2) throw() { 00293 return &al1.space == &al2.space; 00294 } 00295 00302 template<class T1, class T2> 00303 bool operator!=(space_allocator<T1> const& al1, 00304 space_allocator<T2> const& al2) throw() { 00305 return &al1.space != &al2.space; 00306 } 00307 00308 00309 template<class T> struct region_allocator; 00310 00317 template<> 00318 struct region_allocator<void> { 00319 typedef void* pointer; 00320 typedef const void* const_pointer; 00321 typedef void value_type; 00323 template<class U> struct rebind { 00324 typedef region_allocator<U> other; 00325 }; 00326 }; 00327 00336 template<class T> 00337 struct region_allocator { 00339 typedef T value_type; 00341 typedef size_t size_type; 00343 typedef ptrdiff_t difference_type; 00345 typedef T* pointer; 00347 typedef T const* const_pointer; 00349 typedef T& reference; 00351 typedef T const& const_reference; 00352 00354 template<class U> struct rebind { 00356 typedef region_allocator<U> other; 00357 }; 00358 00360 Region& region; 00361 00366 region_allocator(Region& region) throw() 00367 : region(region) {} 00372 region_allocator(region_allocator const& al) throw() 00373 : region(al.region) {} 00378 template<class U> 00379 region_allocator(region_allocator<U> const& al) throw() 00380 : region(al.region) {} 00381 00383 pointer address(reference x) const { return &x; } 00385 const_pointer address(const_reference x) const { return &x; } 00387 size_type max_size() const throw() { 00388 return std::numeric_limits<size_type>::max() 00389 / (sizeof(T)>0 ? sizeof(T) : 1); 00390 } 00391 00400 pointer allocate(size_type count) { 00401 return static_cast<pointer>(region.ralloc(sizeof(T)*count)); 00402 } 00403 00415 pointer allocate(size_type count, const void * const hint) { 00416 (void) hint; 00417 return allocate(count); 00418 } 00419 00428 void deallocate(pointer* p, size_type count) { 00429 region.rfree(static_cast<void*>(p), count); 00430 } 00431 00439 void construct(pointer element, const_reference t) { 00440 new (element) T(t); 00441 } 00442 00444 void destroy(pointer element) { 00445 element->~T(); 00446 } 00447 }; 00448 00449 /* 00450 * \brief Tests two region allocators for equality 00451 * 00452 * Two allocators are equal when each can release storage allocated 00453 * from the other. 00454 */ 00455 template<class T1, class T2> 00456 bool operator==(region_allocator<T1> const& al1, 00457 region_allocator<T2> const& al2) throw() { 00458 return &al1.region == &al2.region; 00459 } 00460 00461 /* 00462 * \brief Tests two region allocators for inequality 00463 * 00464 * Two allocators are equal when each can release storage allocated 00465 * from the other. 00466 */ 00467 template<class T1, class T2> 00468 bool operator!=(region_allocator<T1> const& al1, 00469 region_allocator<T2> const& al2) throw() { 00470 return &al1.region != &al2.region; 00471 } 00472 00473 } 00474 00475 // STATISTICS: kernel-other