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-10-11 12:10:44 +0200 (Mon, 11 Oct 2010) $ by $Author: tack $ 00014 * $Revision: 11514 $ 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 (void) al; 00217 assert(&space == &al.space); 00218 return *this; 00219 } 00224 template<class U> 00225 space_allocator(space_allocator<U> const& al) throw() : space(al.space) {} 00226 00228 pointer address(reference x) const { return &x; } 00230 const_pointer address(const_reference x) const { return &x; } 00232 size_type max_size() const throw() { 00233 return std::numeric_limits<size_type>::max() / 00234 (sizeof(T)>0 ? sizeof(T) : 1); 00235 } 00244 pointer allocate(size_type count) { 00245 return static_cast<pointer>(space.ralloc(sizeof(T)*count)); 00246 } 00247 00258 pointer allocate(size_type count, const void * const hint) { 00259 (void) hint; 00260 return allocate(count); 00261 } 00262 00264 void deallocate(pointer p, size_type count) { 00265 space.rfree(static_cast<void*>(p), count); 00266 } 00267 00268 /* 00269 * \brief Constructs an object 00270 * 00271 * Constructs an object of type \a T with the initial value of \a t 00272 * at the location specified by \a element. This function calls 00273 * the <i>placement new()</i> operator. 00274 */ 00275 void construct(pointer element, const_reference t) { 00276 new (element) T(t); 00277 } 00278 00280 void destroy(pointer element) { 00281 element->~T(); 00282 } 00283 }; 00284 00291 template<class T1, class T2> 00292 bool operator==(space_allocator<T1> const& al1, 00293 space_allocator<T2> const& al2) throw() { 00294 return &al1.space == &al2.space; 00295 } 00296 00303 template<class T1, class T2> 00304 bool operator!=(space_allocator<T1> const& al1, 00305 space_allocator<T2> const& al2) throw() { 00306 return &al1.space != &al2.space; 00307 } 00308 00309 00310 template<class T> struct region_allocator; 00311 00318 template<> 00319 struct region_allocator<void> { 00320 typedef void* pointer; 00321 typedef const void* const_pointer; 00322 typedef void value_type; 00324 template<class U> struct rebind { 00325 typedef region_allocator<U> other; 00326 }; 00327 }; 00328 00337 template<class T> 00338 struct region_allocator { 00340 typedef T value_type; 00342 typedef size_t size_type; 00344 typedef ptrdiff_t difference_type; 00346 typedef T* pointer; 00348 typedef T const* const_pointer; 00350 typedef T& reference; 00352 typedef T const& const_reference; 00353 00355 template<class U> struct rebind { 00357 typedef region_allocator<U> other; 00358 }; 00359 00361 Region& region; 00362 00367 region_allocator(Region& region) throw() 00368 : region(region) {} 00373 region_allocator(region_allocator const& al) throw() 00374 : region(al.region) {} 00379 template<class U> 00380 region_allocator(region_allocator<U> const& al) throw() 00381 : region(al.region) {} 00382 00384 pointer address(reference x) const { return &x; } 00386 const_pointer address(const_reference x) const { return &x; } 00388 size_type max_size() const throw() { 00389 return std::numeric_limits<size_type>::max() 00390 / (sizeof(T)>0 ? sizeof(T) : 1); 00391 } 00392 00401 pointer allocate(size_type count) { 00402 return static_cast<pointer>(region.ralloc(sizeof(T)*count)); 00403 } 00404 00416 pointer allocate(size_type count, const void * const hint) { 00417 (void) hint; 00418 return allocate(count); 00419 } 00420 00429 void deallocate(pointer* p, size_type count) { 00430 region.rfree(static_cast<void*>(p), count); 00431 } 00432 00440 void construct(pointer element, const_reference t) { 00441 new (element) T(t); 00442 } 00443 00445 void destroy(pointer element) { 00446 element->~T(); 00447 } 00448 }; 00449 00450 /* 00451 * \brief Tests two region allocators for equality 00452 * 00453 * Two allocators are equal when each can release storage allocated 00454 * from the other. 00455 */ 00456 template<class T1, class T2> 00457 bool operator==(region_allocator<T1> const& al1, 00458 region_allocator<T2> const& al2) throw() { 00459 return &al1.region == &al2.region; 00460 } 00461 00462 /* 00463 * \brief Tests two region allocators for inequality 00464 * 00465 * Two allocators are equal when each can release storage allocated 00466 * from the other. 00467 */ 00468 template<class T1, class T2> 00469 bool operator!=(region_allocator<T1> const& al1, 00470 region_allocator<T2> const& al2) throw() { 00471 return &al1.region != &al2.region; 00472 } 00473 00474 } 00475 00476 // STATISTICS: kernel-other