Generated on Tue Jul 27 2010 21:59:16 for Gecode by doxygen 1.7.1

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