Generated on Thu Apr 11 13:59:16 2019 for Gecode by doxygen 1.6.3

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  *  This file is part of Gecode, the generic constraint
00013  *  development environment:
00014  *     http://www.gecode.org
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(void) 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(void) 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-memory