Generated on Mon Nov 30 11:16:26 2009 for Gecode by doxygen 1.5.5

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: 2009-11-24 23:12:38 +0100 (Tue, 24 Nov 2009) $ by $Author: schulte $
00014  *     $Revision: 10122 $
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;
00161     template<class U> struct rebind {
00162       typedef space_allocator<U> other;
00163     };
00164   };
00165 
00175   template<class T> 
00176   struct space_allocator {
00178     typedef T value_type;
00180     typedef size_t size_type;
00182     typedef ptrdiff_t difference_type;
00184     typedef T* pointer;
00186     typedef T const* const_pointer;
00188     typedef T& reference;
00190     typedef T const&  const_reference;
00192     template<class U> struct rebind { 
00194       typedef space_allocator<U> other;
00195     };
00196 
00198     Space& space;
00199 
00204     space_allocator(Space& space) throw() : space(space) {}
00209     space_allocator(space_allocator const& al) throw() : space(al.space) {}
00214     space_allocator& operator =(space_allocator const& al) {
00215       assert(&space == &al.space);
00216       return *this;
00217     }
00222     template<class U> 
00223     space_allocator(space_allocator<U> const& al) throw() : space(al.space) {}
00224 
00226     pointer address(reference x) const { return &x; }
00228     const_pointer address(const_reference x) const { return &x; }
00230     size_type max_size() const throw() {
00231       return std::numeric_limits<size_type>::max() / 
00232         (sizeof(T)>0 ? sizeof(T) : 1);
00233     }
00242     pointer allocate(size_type count) {
00243       return static_cast<pointer>(space.ralloc(sizeof(T)*count));
00244     }
00245 
00256     pointer allocate(size_type count, const void * const hint) {
00257       (void) hint;
00258       return allocate(count);
00259     }
00260 
00262     void deallocate(pointer p, size_type count) {
00263       space.rfree(static_cast<void*>(p), count);
00264     }
00265 
00266     /*
00267      * \brief Constructs an object 
00268      *
00269      * Constructs an object of type \a T with the initial value of \a t 
00270      * at the location specified by \a element. This function calls 
00271      * the <i>placement new()</i> operator.
00272      */
00273     void construct(pointer element, const_reference t) {
00274       new (element) T(t);
00275     }
00276 
00278     void destroy(pointer element) {
00279       element->~T();
00280     }
00281   };
00282 
00289   template<class T1, class T2>
00290   bool operator==(space_allocator<T1> const& al1, 
00291                   space_allocator<T2> const& al2) throw() {
00292     return &al1.space == &al2.space;
00293   }
00294 
00301   template<class T1, class T2>
00302   bool operator!=(space_allocator<T1> const& al1, 
00303                   space_allocator<T2> const& al2) throw() {
00304     return &al1.space != &al2.space;
00305   }
00306 
00307 
00308   template<class T> struct region_allocator;
00309 
00316   template<> 
00317   struct region_allocator<void> {
00318     typedef void* pointer;
00319     typedef const void* const_pointer;
00320     typedef void value_type;
00321     template<class U> struct rebind {
00322       typedef region_allocator<U> other;
00323     };
00324   };
00325 
00334   template<class T> 
00335   struct region_allocator {
00337     typedef T value_type;
00339     typedef size_t size_type;
00341     typedef ptrdiff_t difference_type;
00343     typedef T* pointer;
00345     typedef T const*  const_pointer;
00347     typedef T&  reference;
00349     typedef T const& const_reference;
00350 
00352     template<class U> struct rebind { 
00354      typedef region_allocator<U> other;
00355     };
00356 
00358     Region& region;
00359 
00364     region_allocator(Region& region) throw() 
00365       : region(region) {}
00370     region_allocator(region_allocator const& al) throw() 
00371       : region(al.region) {}
00376     template<class U> 
00377     region_allocator(region_allocator<U> const& al) throw() 
00378       : region(al.region) {}
00379 
00381     pointer address(reference x) const { return &x; }
00383     const_pointer address(const_reference x) const { return &x; }
00385     size_type max_size() const throw() {
00386       return std::numeric_limits<size_type>::max() 
00387         / (sizeof(T)>0 ? sizeof(T) : 1);
00388     }
00389 
00398     pointer allocate(size_type count) {
00399       return static_cast<pointer>(region.ralloc(sizeof(T)*count));
00400     }
00401 
00413     pointer allocate(size_type count, const void * const hint) {
00414       (void) hint;
00415       return allocate(count);
00416     }
00417     
00426     void deallocate(pointer* p, size_type count) {
00427       region.rfree(static_cast<void*>(p), count);
00428     }
00429 
00437      void construct(pointer element, const_reference t) {
00438       new (element) T(t);
00439     }
00440 
00442     void destroy(pointer element) {
00443       element->~T();
00444     }
00445   };
00446 
00447   /*
00448    * \brief Tests two region allocators for equality
00449    *
00450    * Two allocators are equal when each can release storage allocated 
00451    * from the other.
00452    */
00453   template<class T1, class T2>
00454   bool operator==(region_allocator<T1> const& al1, 
00455                   region_allocator<T2> const& al2) throw() {
00456     return &al1.region == &al2.region;
00457   }
00458 
00459   /*
00460    * \brief Tests two region allocators for inequality
00461    *
00462    * Two allocators are equal when each can release storage allocated
00463    * from the other.
00464    */
00465   template<class T1, class T2>
00466   bool operator!=(region_allocator<T1> const& al1, 
00467                   region_allocator<T2> const& al2) throw() {
00468     return &al1.region != &al2.region;
00469   }
00470 
00471 }
00472 
00473 // STATISTICS: kernel-other