BWAPI
SPAR/AIModule/BWTA/vendors/CGAL/CGAL/Handle_with_policy.h
Go to the documentation of this file.
00001 // Copyright (c) 2001-2007 Max-Planck-Institute Saarbruecken (Germany).
00002 // All rights reserved.
00003 //
00004 // This file is part of CGAL (www.cgal.org); you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public License as
00006 // published by the Free Software Foundation; version 2.1 of the License.
00007 // See the file LICENSE.LGPL distributed with CGAL.
00008 //
00009 // Licensees holding a valid commercial license may use this file in
00010 // accordance with the commercial license agreement provided with the software.
00011 //
00012 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00013 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00014 //
00015 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/STL_Extension/include/CGAL/Handle_with_policy.h $
00016 // $Id: Handle_with_policy.h 44351 2008-07-23 13:19:15Z hoffmann $
00017 //
00018 // Author(s)     : Michael Seel <seel@mpi-inf.mpg.de>
00019 //                 Arno Eigenwillig <arno@mpi-inf.mpg.de>
00020 //                 Lutz Kettner <kettner@mpi-inf.mpg.de>
00021 
00022 #ifndef CGAL_HANDLE_WITH_POLICY_H
00023 #define CGAL_HANDLE_WITH_POLICY_H
00024 
00025 #include <CGAL/basic.h>
00026 #include <CGAL/memory.h>
00027 #include <CGAL/type_traits.h>
00028 
00029 #include <boost/static_assert.hpp>
00030 #include <boost/mpl/if.hpp>
00031 
00032 #include <cstddef>
00033 
00034 #ifdef CGAL_USE_LEDA
00035 #  if CGAL_LEDA_VERSION < 500
00036 #    include <LEDA/memory.h>
00037 #  else
00038 #    include <LEDA/system/memory.h>
00039 #  endif
00040 #endif
00041 
00042 
00043 
00044 CGAL_BEGIN_NAMESPACE
00045 
00171 
00172 // Forward declarations of HandlePolicy classes
00173 class Handle_policy_in_place;
00174 class Handle_policy_no_union;
00175 class Handle_policy_union;
00176 class Handle_policy_union_and_reset;
00177 
00178 // Reference counted representation
00179 // ================================
00180 
00182 template <class T>
00183 class Reference_counted {
00184 public:
00185     typedef Reference_counted<T> Self;
00186     typedef T*  Rep_pointer;
00187 private:
00188     mutable unsigned int count;  // reference counter
00189     T                    rep;
00190 public:
00191     Reference_counted() : count(1) {}
00192     Reference_counted( const T& t) : count(1), rep(t) {}
00193     Reference_counted( const Self& r) : count(1), rep(r.rep) {}
00194 
00195     void clear() { rep = T(); }
00196     Rep_pointer  base_ptr()  { return &rep; }
00197     void add_reference()     { ++count; }
00198     void remove_reference()  { --count; }
00199     bool is_shared() const   { return count > 1; }
00200     int  union_size() const  { return 1+count; }
00201     void add_union_size(int) {}
00202 };
00203 
00208 template <class T>
00209 class Reference_counted_with_forwarding {
00210 public:
00211     typedef Reference_counted_with_forwarding<T> Self;
00212     typedef T*  Rep_pointer;
00213     friend class Handle_policy_union;
00214     friend class Handle_policy_union_and_reset;
00215 private:
00216     mutable unsigned int count;  // reference counter
00217     mutable Self*        next;   // forwarding pointer to valid rep or 0
00218     mutable int          u_size; // union set size incl this rep and its handle
00219     mutable T            rep;
00220 public:
00221     Reference_counted_with_forwarding()
00222         : count(1), next(0), u_size(2) {}
00223     Reference_counted_with_forwarding( const T& t)
00224         : count(1), next(0), u_size(2), rep(t) {}
00225     Reference_counted_with_forwarding( const Self& r)
00226         : count(1), next(0), u_size(2), rep(r.rep) {}
00227 
00228     void clear() { rep = T(); }
00229     Rep_pointer  base_ptr()    { return &rep; }
00230     void add_reference()       { ++count; }
00231     void remove_reference()    { --count; }
00232     bool is_shared() const     { return count > 1; }
00233     bool is_forwarding() const { return next != 0; }
00234     int  union_size() const    { return u_size; }
00235     void add_union_size(int a) {  
00236         CGAL_precondition( u_size + a > 0);
00237         u_size += a;
00238     }
00239 };
00240 
00241 
00242 struct Reference_counted_hierarchy_base {};
00243 
00244 
00249 template <class Allocator_  = CGAL_ALLOCATOR(char)>
00250 class Reference_counted_hierarchy : public Reference_counted_hierarchy_base {
00251     // make sure it's always a char allocator
00252     typedef typename Allocator_::template rebind< char> Char_alloc_rebind;
00253     typedef typename Char_alloc_rebind::other   Char_allocator;
00254 
00255     static Char_allocator alloc;
00256 
00257 public:
00258     void* operator new(size_t bytes) { return alloc.allocate( bytes); }
00259     void  operator delete(void* p, size_t bytes) { 
00260         alloc.deallocate((char*)p, bytes);
00261     }
00262 
00263 public:
00264     typedef Allocator_ Allocator;
00265     typedef Reference_counted_hierarchy<Allocator> Self;
00266     typedef Self*  Rep_pointer;
00267 private:
00268     mutable unsigned int count;  // reference counter
00269 public:
00270     Reference_counted_hierarchy() : count(1) {}
00271     Reference_counted_hierarchy( const Self&) : count(1) {}
00272 
00273     Rep_pointer base_ptr()   { return this; }
00274     void add_reference()     { ++count; }
00275     void remove_reference()  { --count; }
00276     bool is_shared() const   { return count > 1; }
00277     int  union_size() const  { return 1+count; }
00278     void add_union_size(int) {}
00279 
00282     virtual Self* clone() = 0;
00284     virtual ~Reference_counted_hierarchy() {}
00291     virtual void clear() {}
00292 };
00293 
00294 template <class Alloc>
00295 typename Reference_counted_hierarchy<Alloc>::Char_allocator
00296     Reference_counted_hierarchy<Alloc>::alloc;
00297 
00302 template <class Allocator_  = CGAL_ALLOCATOR(char)>
00303 class Reference_counted_hierarchy_with_union 
00304     : public Reference_counted_hierarchy<Allocator_> 
00305 {
00306     friend class Handle_policy_union;
00307     friend class Handle_policy_union_and_reset;
00308 public:
00309     typedef Allocator_ Allocator;
00310     typedef Reference_counted_hierarchy_with_union<Allocator> Self;
00311 private:
00312     mutable Self*        next;   // forwarding pointer to valid rep or 0
00313     mutable int          u_size; // union set size incl this rep and its handle
00314 public:
00315     Reference_counted_hierarchy_with_union() : 
00316         Reference_counted_hierarchy<Allocator_>(), next(0), u_size(2) {}
00317     bool is_forwarding() const { return next != 0; }
00318     int  union_size() const    { return u_size; }
00319     void add_union_size(int a) {  
00320         CGAL_precondition( u_size + a > 0);
00321         u_size += a;
00322     }
00323 };
00324 
00325 
00326 // Handle for reference counted representation
00327 // ===========================================
00328 
00329 namespace Intern {
00330     // Some helper classes to select representation between single class
00331     // representations and class hierarchy representations.
00332 
00333     // the representation type including a reference counter. 
00334     // The handle allocates objects of this type. This is the version
00335     // for the single representation type.
00336     template <class T, int HandleHierarchyPolicy>
00337     struct Rep_bind_reference_counted {
00338         typedef Reference_counted<T> Rep;
00339     };
00340 
00341     // the representation type including a reference counter. 
00342     // The handle allocates objects of this type. This is the version
00343     // for the class hierarchy of representation types.
00344     template <class T>
00345     struct Rep_bind_reference_counted<T, true> {
00346         typedef T Rep;
00347     };
00348 
00349     // the two versions for Reference_counted_with_forwarding
00350     template <class T, int HandleHierarchyPolicy>
00351     struct Rep_bind_reference_counted_with_forwarding {
00352         typedef Reference_counted_with_forwarding<T> Rep;
00353     };
00354 
00355     // the representation type including a reference counter. 
00356     // The handle allocates objects of this type. This is the version
00357     // for the class hierarchy of representation types.
00358     template <class T>
00359     struct Rep_bind_reference_counted_with_forwarding<T, true> {
00360         Rep_bind_reference_counted_with_forwarding() {
00361             // make sure we derived from the right type 
00362             typedef typename T::Allocator Alloc;
00363             typedef ::CGAL::Reference_counted_hierarchy_with_union<Alloc> 
00364                 Reference_counted_hierarchy_with_union;
00365             BOOST_STATIC_ASSERT((
00366               ::CGAL::is_same_or_derived< Reference_counted_hierarchy_with_union, T >::value ));
00367         }
00368         typedef T Rep;
00369     };
00370 
00371 }
00372 
00382 class Handle_policy_in_place {};
00383 
00388 class Handle_policy_no_union {
00389 public:
00393     template <class T, int hierarchy>
00394     struct Rep_bind {
00397         typedef typename 
00398             Intern::Rep_bind_reference_counted<T,hierarchy>::Rep Rep;
00399     };
00400 
00410     template <class Alloc>
00411     struct Hierarchy_base {
00413         typedef Reference_counted_hierarchy<Alloc> Type;
00414     };
00415     
00422     template <class H>
00423     static void unify( const H& h, const H& g) {
00424         (void)h; // avoid warnings for unused parameters
00425         (void)g; // but keep the names in the definition for the doc.
00426     }
00427 
00430     template <class H>
00431     static typename H::Rep_pointer find( const H& h) {
00432         return h.ptr_->base_ptr();
00433     }
00434 };
00435 
00441 class Handle_policy_union {
00442 public:
00446     template <class T, int hierarchy>
00447     struct Rep_bind {
00449         Rep_bind() {
00450           //Intern::Rep_bind_reference_counted_with_forwarding<T, hierarchy>
00451           //     check;
00452           //  (void)check;
00453           (void)Intern::Rep_bind_reference_counted_with_forwarding<T, hierarchy>();
00454         }
00457         typedef typename Intern::Rep_bind_reference_counted_with_forwarding<T,
00458             hierarchy>::Rep Rep;
00459     };
00460 
00470     template <class Alloc>
00471     struct Hierarchy_base {
00473         typedef Reference_counted_hierarchy_with_union<Alloc> Type;
00474     };
00475     
00484     template <class H>
00485     static void unify_large_small( const H& h, const H& g) {
00486         typename H::Rep* hrep = h.ptr_;
00487         typename H::Rep* grep = g.ptr_;
00488         CGAL_precondition( ! grep->is_forwarding());
00489         CGAL_precondition( hrep->union_size() >= grep->union_size());
00490         grep->add_union_size(-1);
00491         // make g point to h's rep.
00492         if ( grep->is_shared()) {
00493             // grep survises the loss of one reference 
00494             // and hrep gets one more reference
00495             grep->remove_reference();
00496             hrep->add_reference();
00497             hrep->add_union_size( grep->union_size());
00498             grep->next = hrep;
00499         } else {
00500             g.delete_rep( grep); // did not survive loss of handle g
00501         }
00502         // redirect handle g and incr. hrep's counter
00503         g.ptr_ = hrep;
00504         hrep->add_reference();
00505         hrep->add_union_size(1);
00506     }
00507 
00513     template <class H>
00514     static void unify( const H& h, const H& g) {
00515         if ( find(h) !=  find(g)) {
00516             if ( h.ptr_->union_size() > g.ptr_->union_size())
00517                 unify_large_small( h, g); // make g point to h's rep.
00518             else
00519                 unify_large_small( g, h); // make h point to g's rep.
00520         }
00521     }
00522 
00527     template <class H>
00528     static typename H::Rep_pointer find( const H& h) {
00529         typedef typename H::Rep Rep;
00530         if ( h.ptr_->is_forwarding()) {
00531             // find new valid representation
00532             Rep* new_rep = h.ptr_;
00533             while ( new_rep->next != 0)
00534                 new_rep = static_cast<Rep*>(new_rep->next);
00535             // path compression: assign new rep to all reps seen on the path
00536             // update reference count properly: all reps on the path loose
00537             // one reference, and the new_rep gains all of them unless
00538             // the rep on the path get actually deleted.
00539             Rep* rep = h.ptr_;
00540             while ( rep != new_rep) {
00541                 Rep* tmp = static_cast<Rep*>(rep->next);
00542                 if ( rep->is_shared()) {
00543                     // rep survives the loss of one reference 
00544                     // and new_rep gets one more reference
00545                     rep->remove_reference();
00546                     if ( tmp != new_rep) {
00547                         // re-link rep to the new_rep
00548                         rep->next = new_rep;
00549                         new_rep->add_reference();
00550                     }
00551                 } else {
00552                     h.delete_rep( rep); // we have to delete the current rep
00553                 }                
00554                 rep = tmp;
00555             }
00556             // hook h to new_rep
00557             h.ptr_ = new_rep;
00558             new_rep->add_reference();
00559         }
00560         return h.ptr_->base_ptr();
00561     }
00562 };
00563 
00573 class Handle_policy_union_and_reset {
00574 public:
00578     template <class T, int hierarchy>
00579     struct Rep_bind {
00581         Rep_bind() {
00582           //Intern::Rep_bind_reference_counted_with_forwarding<T, hierarchy>
00583           //     check;
00584           // (void)check;
00585           (void)Intern::Rep_bind_reference_counted_with_forwarding<T, hierarchy>();
00586         }
00589         typedef typename Intern::Rep_bind_reference_counted_with_forwarding<T,
00590             hierarchy>::Rep Rep;
00591     };
00592 
00602     template <class Alloc>
00603     struct Hierarchy_base {
00605         typedef Reference_counted_hierarchy_with_union<Alloc> Type;
00606     };
00607 
00608     // abbreviation to re-use its implementation below.
00609     typedef Handle_policy_union U;
00610 
00618     template <class H>
00619     static void unify( const H& h, const H& g) {
00620         if ( find(h) !=  find(g)) {
00621             if ( h.ptr_->union_size() > g.ptr_->union_size()) {
00622                 // reset representation in g to default construction of T
00623                 if ( g.ptr_->is_shared())
00624                     g.ptr_->clear();
00625                 U::unify_large_small( h, g); // make g point to h's rep.
00626             } else {
00627                 // reset representation in h to default construction of T
00628                 if ( h.ptr_->is_shared())
00629                     h.ptr_->clear();
00630                 U::unify_large_small( g, h); // make h point to g's rep.
00631             }
00632         }
00633     }
00634 
00639     template <class H>
00640     static typename H::Rep_pointer find( const H& h) { return U::find(h); }
00641 };
00642 
00643 
00710 template <class T, 
00711           class HandlePolicy = Handle_policy_no_union, 
00712           class Allocator_ = CGAL_ALLOCATOR(T)>
00713 class Handle_with_policy {
00714 public:
00716     typedef Handle_with_policy< T, HandlePolicy, Allocator_>    Self;
00717 
00719     typedef HandlePolicy                Handle_policy;
00720 
00722     typedef Allocator_                  Allocator;
00723 
00724     enum { is_class_hierarchy  = 
00725         ::CGAL::is_same_or_derived< Reference_counted_hierarchy_base, T>::value };
00726     typedef typename Handle_policy::template Rep_bind< T, is_class_hierarchy > Bind;
00727     // instantiate Rep_bind to activate compile time check in there
00728     static Bind bind;
00729     // Define type that is used for function matching 
00730     typedef typename ::boost::mpl::if_c< 
00731          is_class_hierarchy, 
00732            ::CGAL::Tag_true, 
00733            ::CGAL::Tag_false >::type 
00734          Class_hierarchy;
00735 
00739     typedef typename Bind::Rep  Rep;
00740 
00741     typedef typename Rep::Rep_pointer  Rep_pointer;
00742 
00743     typedef typename Allocator_::template rebind<Rep>::other  Rep_allocator;
00744 
00745 
00747     typedef std::ptrdiff_t              Id_type;
00748 
00749     friend class Handle_policy_no_union;
00750     friend class Handle_policy_union;
00751     friend class Handle_policy_union_and_reset;
00752 private:
00753     mutable Rep*  ptr_;
00754 
00755     // We have to distinguish between allocating single representations
00756     // and where we have a class hierarchy of representations, where the
00757     // user is responsible for allocating the first representations
00758     // and we can just \c clone and delete them.
00759     static Rep_allocator allocator;
00760 
00761     static Rep* new_rep( const Rep& rep) { 
00762         BOOST_STATIC_ASSERT( !(
00763            ::CGAL::is_same_or_derived< Reference_counted_hierarchy_base, T >::value ));
00764         Rep* p = allocator.allocate(1);
00765         allocator.construct(p, rep);
00766         return p;
00767     }
00768     static void delete_rep( Rep* p, ::CGAL::Tag_false ) {
00769         allocator.destroy( p);
00770         allocator.deallocate( p, 1);
00771     }
00772     static void delete_rep( Rep* p, ::CGAL::Tag_true ) {
00773         delete p;
00774     }
00775     static void delete_rep( Rep* p) { delete_rep(p, Class_hierarchy()); }
00776 
00777     static Rep* clone_rep( Rep* p, ::CGAL::Tag_false ) {
00778         return new_rep( *p);
00779     }
00780     static Rep* clone_rep( Rep* p, ::CGAL::Tag_true ) {
00781         return static_cast<Rep*>(p->clone());
00782     }
00783     static Rep* clone_rep( Rep* p) { return clone_rep( p, Class_hierarchy()); }
00784 
00785     void remove_reference() {
00786         // cleans up the possible chain of forwarding reps
00787         Handle_policy::find( *this);
00788         if ( ! is_shared()) {
00789             delete_rep( ptr_);
00790         } else {
00791             ptr_->remove_reference();
00792             ptr_->add_union_size( -1);
00793         }
00794     }
00795 
00796     template <class TT>
00797     Rep* make_from_single_arg( const TT& t, ::CGAL::Tag_false ) {
00798         return new_rep( Rep( T(t)));
00799     }
00800     template <class TT>
00801     Rep* make_from_single_arg( TT t, ::CGAL::Tag_true ) {
00802       //Bind bind_; // trigger compile-time check
00803       // (void)bind_;
00804       (void)Bind(); // shouldn't this be enough to trigger?
00805         return t; // has to be a pointer convertible to Rep*
00806     }
00807 
00808 protected:
00810     T*       ptr()       { return static_cast<T*>(Handle_policy::find(*this));}
00812     const T* ptr() const { 
00813         return static_cast<const T*>(Handle_policy::find( *this));
00814     }
00815 
00820     void unify( const Self& h) const { Handle_policy::unify( *this, h); }
00821 
00826     void copy_on_write() {
00827         Handle_policy::find( *this);
00828         if ( is_shared() ) {
00829             Rep* tmp_ptr = clone_rep( ptr_);
00830             ptr_->remove_reference();
00831             ptr_->add_union_size( -1);
00832             ptr_ = tmp_ptr;
00833         }
00834     }
00835 
00837     enum Use_with_initialize_with {
00838         USE_WITH_INITIALIZE_WITH 
00839 
00840     };
00841 
00848     Handle_with_policy( Use_with_initialize_with) : ptr_( 0) {}
00849 
00856     Handle_with_policy( Rep* p) : ptr_( p) {
00857         BOOST_STATIC_ASSERT((
00858            ::CGAL::is_same_or_derived< Reference_counted_hierarchy_base, T >::value ));
00859         //Bind bind_; // trigger compile-time check
00860         //(void)bind_;
00861         (void)Bind();
00862     }
00863 
00870     void initialize_with( Rep* p) {
00871         BOOST_STATIC_ASSERT((
00872            ::CGAL::is_same_or_derived< Reference_counted_hierarchy_base, T >::value ));
00873         //Bind bind_; // trigger compile-time check
00874         //(void)bind_;
00875         (void)Bind();
00876         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00877                          "representation has already been initialized.");
00878         ptr_ = p;
00879     }
00880 
00887     template <class T1>
00888     void initialize_with( const T1& t1) {
00889         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00890                          "representation has already been initialized.");
00891         ptr_ = make_from_single_arg( t1, Class_hierarchy());
00892     }
00893 
00896     template <class T1, class T2>
00897     void initialize_with( const T1& t1, const T2& t2) {
00898         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00899                          "representation has already been initialized.");
00900         ptr_ = new_rep( Rep( T(t1,t2)));
00901     }
00902 
00905     template <class T1, class T2, class T3>
00906     void initialize_with( const T1& t1, const T2& t2, const T3& t3) {
00907         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00908                          "representation has already been initialized.");
00909         ptr_ = new_rep( Rep( T(t1,t2,t3)));
00910     }
00911 
00914     template <class T1, class T2, class T3, class T4>
00915     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
00916                           const T4& t4) {
00917         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00918                          "representation has already been initialized.");
00919         ptr_ = new_rep( Rep( T(t1,t2,t3,t4)));
00920     }
00921 
00924     template <class T1, class T2, class T3, class T4, class T5>
00925     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
00926                           const T4& t4, const T5& t5) {
00927         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00928                          "representation has already been initialized.");
00929         ptr_ = new_rep( Rep( T(t1,t2,t3,t4,t5)));
00930     }
00931 
00934     template <class T1, class T2, class T3, class T4, class T5, class T6>
00935     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
00936                           const T4& t4, const T5& t5, const T6& t6) {
00937         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00938                          "representation has already been initialized.");
00939         ptr_ = new_rep( Rep( T(t1,t2,t3,t4,t5,t6)));
00940     }
00941 
00944     template <class T1, class T2, class T3, class T4, class T5, class T6,
00945               class T7>
00946     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
00947                           const T4& t4, const T5& t5, const T6& t6,
00948                           const T7& t7) {
00949         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00950                          "representation has already been initialized.");
00951         ptr_ = new_rep( Rep( T(t1,t2,t3,t4,t5,t6,t7)));
00952     }
00953 
00956     template <class T1, class T2, class T3, class T4, class T5, class T6,
00957               class T7, class T8>
00958     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
00959                           const T4& t4, const T5& t5, const T6& t6,
00960                           const T7& t7, const T8& t8) {
00961         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00962                          "representation has already been initialized.");
00963         ptr_ = new_rep( Rep( T(t1,t2,t3,t4,t5,t6,t7,t8)));
00964     }
00965 
00968     template <class T1, class T2, class T3, class T4, class T5, class T6,
00969               class T7, class T8, class T9>
00970     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
00971                           const T4& t4, const T5& t5, const T6& t6,
00972                           const T7& t7, const T8& t8, const T9& t9) {
00973         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
00974                          "representation has already been initialized.");
00975         ptr_ = new_rep( Rep( T(t1,t2,t3,t4,t5,t6,t7,t8,t9)));
00976     }
00977 
00978 public:
00980     Handle_with_policy() : ptr_( new_rep( Rep())) {}
00981 
00983     Handle_with_policy(const Self& h) {
00984         CGAL_precondition_msg( h.ptr_ != 0, "Handle_with_policy::Handle_with_policy( Self): probably "
00985                          "used special protected constructor and not the "
00986                          "'initialize_with()' function.");
00987         Handle_policy::find( h);
00988         ptr_ = h.ptr_;
00989         ptr_->add_reference();
00990         ptr_->add_union_size( 1);
00991     }
00992 
00998     template <class T1>
00999     explicit Handle_with_policy( const T1& t) 
01000         : ptr_( make_from_single_arg( t, Class_hierarchy())) {}
01001 
01004     template <class T1, class T2>
01005     Handle_with_policy( const T1& t1, const T2& t2) : ptr_( new_rep( Rep( T( t1, t2)))) {}
01006 
01009     template <class T1, class T2, class T3>
01010     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3) 
01011         : ptr_( new_rep( Rep( T( t1, t2, t3)))) {}
01012 
01015     template <class T1, class T2, class T3, class T4>
01016     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4) 
01017         : ptr_( new_rep( Rep( T( t1, t2, t3, t4)))) {}
01018 
01021     template <class T1, class T2, class T3, class T4, class T5>
01022     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01023             const T5& t5) 
01024         : ptr_( new_rep( Rep( T( t1, t2, t3, t4, t5)))) {}
01025 
01028     template <class T1, class T2, class T3, class T4, class T5, class T6>
01029     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01030             const T5& t5, const T6& t6) 
01031         : ptr_( new_rep( Rep( T( t1, t2, t3, t4, t5, t6)))) {}
01032 
01035     template <class T1, class T2, class T3, class T4, class T5, class T6, 
01036               class T7>
01037     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01038             const T5& t5, const T6& t6, const T7& t7) 
01039         : ptr_( new_rep( Rep( T( t1, t2, t3, t4, t5, t6, t7)))) {}
01040 
01043     template <class T1, class T2, class T3, class T4, class T5, class T6, 
01044               class T7, class T8>
01045     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01046             const T5& t5, const T6& t6, const T7& t7, const T8& t8) 
01047         : ptr_( new_rep( Rep( T( t1, t2, t3, t4, t5, t6, t7, t8)))) {}
01048 
01051     template <class T1, class T2, class T3, class T4, class T5, class T6, 
01052               class T7, class T8, class T9>
01053     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01054             const T5& t5, const T6& t6, const T7& t7, const T8& t8,
01055             const T9& t9) 
01056         : ptr_( new_rep( Rep( T( t1, t2, t3, t4, t5, t6, t7, t8, t9)))) {}
01057 
01059     ~Handle_with_policy() {
01060       //Bind bind_; // trigger compile-time check
01061       //(void)bind_;
01062       (void)Bind();
01063         CGAL_precondition_msg( ptr_ != 0, "Handle_with_policy::~Handle_with_policy(): probably used "
01064                          "special protected constructor and not the "
01065                          "'initialize_with()' function.");
01066         remove_reference();
01067     }
01068 
01070     Self& operator=( const Self& h) {
01071         CGAL_precondition_msg( h.ptr_ != 0, "Handle_with_policy::operator=(): probably "
01072                          "used special protected constructor and not the "
01073                          "'initialize_with()' function.");
01074         Handle_policy::find( h);
01075         h.ptr_->add_reference();
01076         h.ptr_->add_union_size( 1);
01077         remove_reference();
01078         ptr_ = h.ptr_;
01079         return *this;
01080     }
01081 
01083     bool is_identical( const Self& h) const { return ptr() == h.ptr(); }
01084 
01087     Id_type id() const { return reinterpret_cast<Id_type>(&*ptr()); }
01088 
01091     bool is_shared() const { return ptr_->is_shared(); }
01092 
01096     bool is_forwarding() const { return ptr_->is_forwarding(); }
01097 
01100     int  union_size() const { return ptr_->union_size(); }
01101 
01102     // backwards compatible
01103     bool identical( const Self& h) const { return is_identical(h); }
01104 
01105 #ifdef CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST
01106     // provide access to pointer for testing only!!
01107     const Rep* test_ptr() const { return ptr_; }
01108     // provide access to pointer for testing only!!
01109     bool test_identical_ptr( const Self& h) const { return ptr_ == h.ptr_; }
01110 #endif // CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST
01111 };
01112 
01113 // instantiate Rep_bind to activate compile time check in there
01114 template <class T, class Policy, class Alloc>
01115 typename Handle_with_policy<T,Policy,Alloc>::Bind Handle_with_policy<T,Policy,Alloc>::bind;
01116 
01117 
01119 
01122 template <class T, class A>
01123 unsigned long ID_Number(const Handle_with_policy<T, Handle_policy_no_union, A>& h)
01124     { return h.id(); }
01125 
01126 template <class T, class Policy, class Alloc>
01127 typename Handle_with_policy<T, Policy, Alloc>::Rep_allocator 
01128     Handle_with_policy<T, Policy, Alloc>::allocator;
01129 
01130 
01135 template <class T, class Allocator_>
01136 class Handle_with_policy<T, Handle_policy_in_place, Allocator_> {
01137 public:
01139     typedef Handle_with_policy< T, Handle_policy_in_place, Allocator_>   Self;
01140 
01142     typedef Handle_policy_in_place                           Handle_policy;
01143 
01145     typedef Allocator_                                Allocator;
01146 
01148     typedef T                                         Rep;
01149 
01151     typedef std::ptrdiff_t                            Id_type;
01152 private:
01153     // store the rep in place
01154     Rep  rep;
01155 
01156 protected:
01158     T*       ptr()       { return &rep; }
01160     const T* ptr() const { return &rep; }
01161 
01163     void unify( const Self&) const {}
01164 
01167     void copy_on_write() {}
01168 
01170     enum Use_with_initialize_with {
01171         USE_WITH_INITIALIZE_WITH 
01172     };
01173 
01177     Handle_with_policy( Use_with_initialize_with) {}
01178     
01181     template <class T1>
01182     void initialize_with( const T1& t1) { rep = Rep(t1); }
01183 
01186     template <class T1, class T2>
01187     void initialize_with( const T1& t1, const T2& t2) { rep = Rep(t1,t2); }
01188 
01191     template <class T1, class T2, class T3>
01192     void initialize_with( const T1& t1, const T2& t2, const T3& t3) {
01193         rep = Rep(t1,t2,t3);
01194     }
01195 
01198     template <class T1, class T2, class T3, class T4>
01199     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
01200                           const T4& t4) {
01201         rep = Rep(t1,t2,t3,t4);
01202     }
01203 
01206     template <class T1, class T2, class T3, class T4, class T5>
01207     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
01208                           const T4& t4, const T5& t5) {
01209         rep = Rep(t1,t2,t3,t4,t5);
01210     }
01211 
01214     template <class T1, class T2, class T3, class T4, class T5, class T6>
01215     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
01216                           const T4& t4, const T5& t5, const T6& t6) {
01217         rep = Rep(t1,t2,t3,t4,t5,t6);
01218     }
01219 
01222     template <class T1, class T2, class T3, class T4, class T5, class T6,
01223               class T7>
01224     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
01225                           const T4& t4, const T5& t5, const T6& t6,
01226                           const T7& t7) {
01227         rep = Rep(t1,t2,t3,t4,t5,t6,t7);
01228     }
01229 
01232     template <class T1, class T2, class T3, class T4, class T5, class T6,
01233               class T7, class T8>
01234     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
01235                           const T4& t4, const T5& t5, const T6& t6,
01236                           const T7& t7, const T8& t8) {
01237         rep = Rep(t1,t2,t3,t4,t5,t6,t7,t8);
01238     }
01239 
01242     template <class T1, class T2, class T3, class T4, class T5, class T6,
01243               class T7, class T8, class T9>
01244     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
01245                           const T4& t4, const T5& t5, const T6& t6,
01246                           const T7& t7, const T8& t8, const T9& t9) {
01247         rep = Rep(t1,t2,t3,t4,t5,t6,t7,t8,t9);
01248     }
01249 
01250 public:
01252     Handle_with_policy() {}
01253 
01255     Handle_with_policy(const Self& h) : rep( h.rep) {}
01256 
01259     template <class T1>
01260     explicit Handle_with_policy( const T1& t) : rep( Rep(t)) {}
01261 
01264     template <class T1, class T2>
01265     Handle_with_policy( const T1& t1, const T2& t2) : rep( Rep(t1,t2)) {}
01266 
01269     template <class T1, class T2, class T3>
01270     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3) : rep( Rep(t1,t2,t3)) {}
01271 
01274     template <class T1, class T2, class T3, class T4>
01275     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4) 
01276         : rep( Rep( t1, t2, t3, t4)) {}
01277 
01280     template <class T1, class T2, class T3, class T4, class T5>
01281     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01282             const T5& t5) 
01283         : rep( Rep( t1, t2, t3, t4, t5)) {}
01284 
01287     template <class T1, class T2, class T3, class T4, class T5, class T6>
01288     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01289             const T5& t5, const T6& t6) 
01290         : rep( Rep( t1, t2, t3, t4, t5, t6)) {}
01291 
01294     template <class T1, class T2, class T3, class T4, class T5, class T6, 
01295               class T7>
01296     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01297             const T5& t5, const T6& t6, const T7& t7) 
01298         : rep( Rep( t1, t2, t3, t4, t5, t6, t7)) {}
01299 
01302     template <class T1, class T2, class T3, class T4, class T5, class T6, 
01303               class T7, class T8>
01304     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01305             const T5& t5, const T6& t6, const T7& t7, const T8& t8) 
01306         : rep( Rep( t1, t2, t3, t4, t5, t6, t7, t8)) {}
01307 
01310     template <class T1, class T2, class T3, class T4, class T5, class T6, 
01311               class T7, class T8, class T9>
01312     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
01313             const T5& t5, const T6& t6, const T7& t7, const T8& t8,
01314             const T9& t9) 
01315         : rep( Rep( t1, t2, t3, t4, t5, t6, t7, t8, t9)) {}
01316 
01318     bool is_identical( const Self& h) const { return this == &h; }
01319 
01322     Id_type id() const { return reinterpret_cast<Id_type>(this); }
01323 
01326     bool is_shared() const { return false; }
01327 
01330     bool is_forwarding() const { return false; }
01331 
01333     int  union_size() const { return 1; }
01334 
01335     // backwards compatible
01336     bool identical( const Self& h) const { return is_identical(h); }
01337 
01338 #ifdef CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST
01339     // provide access to pointer for testing only!!
01340     const Rep* test_ptr() const { return *rep; }
01341     // provide access to pointer for testing only!!
01342     bool test_identical_ptr( const Self& h) const { return this == &h; }
01343 #endif // CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST
01344 
01345 #ifdef CGAL_USE_LEDA
01346     LEDA_MEMORY( Self)
01347 #endif
01348 };
01349 
01350 /*\brief
01351  * This class' function call operator test whether one handle's \c id is
01352  * less than the \c id of the other handle.
01353  *
01354  * "Less" is defined in terms of the second template argument,
01355  * which defaults to \c std::less<Handle::Id_type>
01356  */
01357 template <class Handle, class Less = std::less<typename Handle::Id_type> >
01358 class Handle_id_less_than {
01359 public:
01361     typedef bool result_type;
01363     typedef Handle first_argument_type;
01365     typedef Handle second_argument_type;
01367     bool operator () (Handle h1, Handle h2) {
01368         Less is_less;
01369         return is_less(h1.id(), h2.id());
01370     }
01372     bool operator () (Handle h1, Handle h2) const {
01373         Less is_less;
01374         return is_less(h1.id(), h2.id());
01375     }
01376 };
01377 
01378 
01380 
01381 CGAL_END_NAMESPACE
01382 
01383 #endif // CGAL_HANDLE_WITH_POLICY_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines