1 // Copyright (c) 2001-2007 Max-Planck-Institute Saarbruecken (Germany).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org)
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/STL_Extension/include/CGAL/Handle_with_policy.h $
7 // $Id: Handle_with_policy.h 0d66e19 2020-07-24T17:05:10+02:00 Mael Rouxel-Labbé
8 // SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 // Author(s)     : Michael Seel <seel@mpi-inf.mpg.de>
11 //                 Arno Eigenwillig <arno@mpi-inf.mpg.de>
12 //                 Lutz Kettner <kettner@mpi-inf.mpg.de>
13 
14 #ifndef CGAL_HANDLE_WITH_POLICY_H
15 #define CGAL_HANDLE_WITH_POLICY_H
16 
17 #include <CGAL/basic.h>
18 #include <CGAL/memory.h>
19 #include <CGAL/type_traits.h>
20 
21 #include <CGAL/assertions.h>
22 #include <CGAL/use.h>
23 
24 #include <boost/mpl/if.hpp>
25 
26 #include <cstddef>
27 
28 #ifdef CGAL_USE_LEDA
29 #  include <LEDA/system/memory.h>
30 #endif
31 
32 
33 
34 namespace CGAL {
35 
36 /*! \brief <tt>\#include <CGAL/Handle_with_policy.h></tt> for handles with policy
37     parameter for reference counting and union-find strategy. Uses
38     \c LEDA_MEMORY if available.
39 
40     There are two fundamentally different usages of this base class:
41 
42         - with a single representation class. In this case the handle
43           manages allocation and deallocation and the type \c T can
44           be an arbitrary type---the handle adds the necessary reference
45           counter internally.
46 
47         - with a hierarchy of representation classes. Type \c T will be
48           the common base class of this hierarchy and it has to be derived
49           itself from a specific base class, which can be accessed directly
50           or generically from the policy class. The allocator in the
51           handle will not be used in this scenario, since the handle class
52           does not allocate any representations. Instead, the handle class
53           derived from this handle base class is allocating the different
54           representations with the \c new operator. In this case,
55           the allocator in the base class of \c T is used.
56 
57     We give an example for each usage. See also the documentation
58     of \c Handle_with_policy.
59 
60 \b Example
61 
62 We use a single representation class to store an integer. The second
63 constructor makes use of one of the forwarding template constructors
64 that simply forward their parameter list to the representation
65 constructors. They exist for up to ten parameters.  The third
66 constructor illustrates how the \c USE_WITH_INITIALIZE_WITH can be
67 used. It is useful if extensive computations are necessary before the
68 representation can be created.
69 
70 \code
71 struct Int_rep {
72     int val;
73     Int_rep( int i = 0) : val(i) {}
74     Int_rep( int i, int j) : val(i+j) {}
75     Int_rep( int i, int j, int k) : val(i+j+k) {}
76 };
77 
78 template < class Unify>
79 struct Int_t : public Handle_with_policy< Int_rep, Unify > {
80     typedef Handle_with_policy< Int_rep, Unify > Base;
81     Int_t( int i = 0) : Base( i) {}
82     Int_t( int i, int j) : Base( i, j) {}     // template constructors
83     Int_t( int i, int j, int k) : Base( Base::USE_WITH_INITIALIZE_WITH) {
84         initialize_with( i, j + k);
85     }
86     int  value() const { return ptr()->val; }
87     void set_value( int i) {
88         copy_on_write();
89         ptr()->val = i;
90     }
91     bool operator==( const Int_t<Unify>& i) const {
92         bool equal = (value() == i.value());
93         if ( equal)
94             Base::unify(i);
95         return equal;
96     }
97 };
98 \endcode
99 
100 \b Example
101 
102 We use a class hierarchy of two representation classes: one base class
103 for representing one integer, and a derived class to represent an
104 additional integer. To also added virtual get and set functions to
105 make this example similar to the one above.
106 
107 We use the generic solution to pick the base class for \c Int_vrep
108 from the policy class. So all representations are class templates with
109 a policy and an allocator as parameter and the handle class
110 instantiates them. If this flexibility is not needed, one could derive
111 directly from the appropriate base class, i.e., \c
112 ::CGAL::Reference_counted_hierarchy<Alloc> or \c
113 ::CGAL::Reference_counted_hierarchy_with_union<Alloc>. \c Alloc is an
114 allocator of \c char's here.
115 
116 \code
117 template <class Policy, class Alloc>
118 struct Int_vrep : public Policy::Hierarchy_base< Alloc>::Type {
119     int val;
120     virtual ::CGAL::Reference_counted_hierarchy<Alloc>* clone() {
121         return new Int_vrep( *this);
122     }
123     virtual int  get_val() const { return val; }
124     virtual void set_val( int i) { val = i; }
125     Int_vrep( int i = 0) : val(i) {}
126 };
127 
128 template <class Policy, class Alloc>
129 struct Int_vrep2 : public Int_vrep<Policy,Alloc> {
130     int val2;
131     virtual ::CGAL::Reference_counted_hierarchy<Alloc>* clone() {
132         return new Int_vrep2( *this);
133     }
134     virtual int get_val() const { return val + val2; }
135     virtual void set_val( int i) { val = i - val2; }
136     Int_vrep2( int i, int j) : Int_vrep<Policy,Alloc>(i), val2(j) {}
137 };
138 
139 template < class Unify, class Alloc = CGAL_ALLOCATOR(char) >
140 struct Int_vt : public Handle_with_policy< Int_vrep<Unify,Alloc>, Unify > {
141     typedef Handle_with_policy< Int_vrep<Unify,Alloc>, Unify > Base;
142     Int_vt( int i = 0) : Base( new Int_vrep<Unify,Alloc>(i)) {}
143     Int_vt( int i, int j) : Base( new Int_vrep2<Unify,Alloc>(i,j)) {}
144 
145     int  value() const { return ptr()->get_val(); }
146     void set_value( int i) {
147         copy_on_write();
148         ptr()->set_val(i);
149     }
150     bool operator==( const Int_vt<Unify>& i) const {
151         bool equal = (value() == i.value());
152         if ( equal)
153             Base::unify(i);
154         return equal;
155     }
156 };
157 \endcode
158 
159 */
160 //@{
161 
162 // Forward declarations of HandlePolicy classes
163 class Handle_policy_in_place;
164 class Handle_policy_no_union;
165 class Handle_policy_union;
166 class Handle_policy_union_and_reset;
167 
168 // Reference counted representation
169 // ================================
170 
171 //! the base class for bodies of reference counted representations \c T.
172 template <class T_>
173 class Reference_counted {
174 public:
175     typedef T_                          rep_type;
176     typedef Reference_counted<rep_type> Self;
177     typedef rep_type*                   Rep_pointer;
178 private:
179     mutable unsigned int count;  // reference counter
180     rep_type             rep;
181 public:
Reference_counted()182     Reference_counted() : count(1) {}
Reference_counted(const rep_type & t)183     Reference_counted( const rep_type& t) : count(1), rep(t) {}
Reference_counted(const Self & r)184     Reference_counted( const Self& r) : count(1), rep(r.rep) {}
185 
clear()186     void clear() { rep = rep_type(); }
base_ptr()187     Rep_pointer  base_ptr()  { return &rep; }
add_reference()188     void add_reference()     { ++count; }
remove_reference()189     void remove_reference()  { --count; }
is_shared()190     bool is_shared() const   { return count > 1; }
union_size()191     int  union_size() const  { return 1+count; }
add_union_size(int)192     void add_union_size(int) {}
193 };
194 
195 /*!\brief
196  * Base class for bodies of reference counted representations \c T
197  * with a forwarding pointer for identical representations.
198  */
199 template <class T_>
200 class Reference_counted_with_forwarding {
201 public:
202     typedef T_ rep_type;
203     typedef Reference_counted_with_forwarding<rep_type> Self;
204     typedef rep_type*  Rep_pointer;
205     friend class Handle_policy_union;
206     friend class Handle_policy_union_and_reset;
207 private:
208     mutable unsigned int count;  // reference counter
209     mutable Self*        next;   // forwarding pointer to valid rep or 0
210     mutable int          u_size; // union set size incl this rep and its handle
211     mutable rep_type     rep;
212 public:
Reference_counted_with_forwarding()213     Reference_counted_with_forwarding()
214         : count(1), next(0), u_size(2) {}
Reference_counted_with_forwarding(const rep_type & t)215     Reference_counted_with_forwarding( const rep_type& t)
216         : count(1), next(0), u_size(2), rep(t) {}
Reference_counted_with_forwarding(const Self & r)217     Reference_counted_with_forwarding( const Self& r)
218         : count(1), next(0), u_size(2), rep(r.rep) {}
219 
clear()220     void clear() { rep = rep_type(); }
base_ptr()221     Rep_pointer  base_ptr()    { return &rep; }
add_reference()222     void add_reference()       { ++count; }
remove_reference()223     void remove_reference()    { --count; }
is_shared()224     bool is_shared() const     { return count > 1; }
is_forwarding()225     bool is_forwarding() const { return next != 0; }
union_size()226     int  union_size() const    { return u_size; }
add_union_size(int a)227     void add_union_size(int a) {
228         CGAL_precondition( u_size + a > 0);
229         u_size += a;
230     }
231 };
232 
233 
234 struct Reference_counted_hierarchy_base {};
235 
236 
237 /*!\brief Base class for reference counted representations with a class
238  * hierarchy of different representations. Needs an allocator for \c char's
239  * as parameter.
240  */
241 template <class Allocator_  = CGAL_ALLOCATOR(char)>
242 class Reference_counted_hierarchy : public Reference_counted_hierarchy_base {
243     // make sure it's always a char allocator
244     typedef std::allocator_traits<Allocator_> Allocator_traits;
245     typedef typename Allocator_traits::template rebind_alloc<char> Char_allocator;
246 
247     static Char_allocator alloc;
248 
249 public:
new(size_t bytes)250     void* operator new(size_t bytes) { return alloc.allocate( bytes); }
delete(void * p,size_t bytes)251     void  operator delete(void* p, size_t bytes) {
252         alloc.deallocate((char*)p, bytes);
253     }
254 
255 public:
256     typedef Allocator_ Allocator;
257     typedef Reference_counted_hierarchy<Allocator> Self;
258     typedef Self*  Rep_pointer;
259 private:
260     mutable unsigned int count;  // reference counter
261 public:
Reference_counted_hierarchy()262     Reference_counted_hierarchy() : count(1) {}
Reference_counted_hierarchy(const Self &)263     Reference_counted_hierarchy( const Self&) : count(1) {}
264 
base_ptr()265     Rep_pointer base_ptr()   { return this; }
add_reference()266     void add_reference()     { ++count; }
remove_reference()267     void remove_reference()  { --count; }
is_shared()268     bool is_shared() const   { return count > 1; }
union_size()269     int  union_size() const  { return 1+count; }
add_union_size(int)270     void add_union_size(int) {}
271 
272     //! returns a copy of \c this. Can be implemented like
273     //! <tt>return new Derived_type( *this);</tt>
274     virtual Self* clone() = 0;
275     //! the virtual destructor is essential for proper memory management here.
~Reference_counted_hierarchy()276     virtual ~Reference_counted_hierarchy() {}
277     //! can be used to minimize memory consumption once it is known that this
278     //! representation is not used anymore and only needed to keep a fowarding
279     //! pointer. One example would be cleaning up dynamically allocated
280     //! data, or another example would be overwriting a \c leda::real with
281     //! a default constructed value to free its old expression tree. However,
282     //! this function can also be savely ignored and kept empty.
clear()283     virtual void clear() {}
284 };
285 
286 template <class Alloc>
287 typename Reference_counted_hierarchy<Alloc>::Char_allocator
288     Reference_counted_hierarchy<Alloc>::alloc;
289 
290 /*!\brief Base class for reference counted representations with a class
291  * hierarchy of different representations. Needs an allocator for \c char's
292  * as parameter.
293  */
294 template <class Allocator_  = CGAL_ALLOCATOR(char)>
295 class Reference_counted_hierarchy_with_union
296     : public Reference_counted_hierarchy<Allocator_>
297 {
298     friend class Handle_policy_union;
299     friend class Handle_policy_union_and_reset;
300 public:
301     typedef Allocator_ Allocator;
302     typedef Reference_counted_hierarchy_with_union<Allocator> Self;
303 private:
304     mutable Self*        next;   // forwarding pointer to valid rep or 0
305     mutable int          u_size; // union set size incl this rep and its handle
306 public:
Reference_counted_hierarchy_with_union()307     Reference_counted_hierarchy_with_union() :
308         Reference_counted_hierarchy<Allocator_>(), next(0), u_size(2) {}
is_forwarding()309     bool is_forwarding() const { return next != 0; }
union_size()310     int  union_size() const    { return u_size; }
add_union_size(int a)311     void add_union_size(int a) {
312         CGAL_precondition( u_size + a > 0);
313         u_size += a;
314     }
315 };
316 
317 
318 // Handle for reference counted representation
319 // ===========================================
320 
321 namespace Intern {
322     // Some helper classes to select representation between single class
323     // representations and class hierarchy representations.
324 
325     // the representation type including a reference counter.
326     // The handle allocates objects of this type. This is the version
327     // for the single representation type.
328     template <class T, int HandleHierarchyPolicy>
329     struct Rep_bind_reference_counted {
330         typedef Reference_counted<T> Rep;
331     };
332 
333     // the representation type including a reference counter.
334     // The handle allocates objects of this type. This is the version
335     // for the class hierarchy of representation types.
336     template <class T>
337     struct Rep_bind_reference_counted<T, true> {
338         typedef T Rep;
339     };
340 
341     // the two versions for Reference_counted_with_forwarding
342     template <class T, int HandleHierarchyPolicy>
343     struct Rep_bind_reference_counted_with_forwarding {
344         typedef Reference_counted_with_forwarding<T> Rep;
345     };
346 
347     // the representation type including a reference counter.
348     // The handle allocates objects of this type. This is the version
349     // for the class hierarchy of representation types.
350     template <class T>
351     struct Rep_bind_reference_counted_with_forwarding<T, true> {
352         Rep_bind_reference_counted_with_forwarding() {
353             // make sure we derived from the right type
354             typedef typename T::Allocator Alloc;
355             typedef ::CGAL::Reference_counted_hierarchy_with_union<Alloc>
356                 Reference_counted_hierarchy_with_union;
357             CGAL_USE_TYPE(Reference_counted_hierarchy_with_union);
358             CGAL_static_assertion((
359               ::CGAL::is_same_or_derived< Reference_counted_hierarchy_with_union, T >::value ));
360         }
361         typedef T Rep;
362     };
363 
364 }
365 
366 /*! \brief Policy class for \c Handle_with_policy that stores the
367     representation directly without reference counting and without dynamic
368     memory allocation, is actually \e not a model of the \c HandlePolicy
369     concept, but can be  used instead of one. It selects a different
370     specialized implementation of \c Handle_with_policy. It works only with
371     the single representation type, not with a class hierarchy of
372     representation types since they need the pointer in the handle
373     for the polymorphy.
374 */
375 class Handle_policy_in_place {};
376 
377 /*!\brief
378  * Policy class for \c Handle_with_policy<T> that ignores unifying of
379  * identical representations \c T, is a model of the \c HandlePolicy concept.
380  */
381 class Handle_policy_no_union {
382 public:
383     /*!\brief
384      * A rebind mechanism to create the representation type.
385      */
386     template <class T, int hierarchy>
387     struct Rep_bind {
388         //! the representation type including a reference counter.
389         //! The handle allocates objects of this type.
390         typedef typename
391             Intern::Rep_bind_reference_counted<T,hierarchy>::Rep Rep;
392     };
393 
394     /*!\brief
395      * A rebind mechanism to access the base class for class hierarchies
396      * of representations.
397      *
398      * The base classes can be used directly, but this
399      * rebind mechamism allows the implementation of handle-rep classes
400      * that are parameterized with the policy class only and adapt to
401      * the necessary base class.
402      */
403     template <class Alloc>
404     struct Hierarchy_base {
405         //! type that can be used as base class for the representation type.
406         typedef Reference_counted_hierarchy<Alloc> Type;
407     };
408 
409     /*! \brief unifies the representations of the two handles \a h and \a g.
410      *  The effect is void here.
411      *
412      * \pre The representations represent the same value and one could be
413      *  replaced by the other.
414     */
415     template <class H>
416     static void unify( const H& h, const H& g) {
417         (void)h; // avoid warnings for unused parameters
418         (void)g; // but keep the names in the definition for the doc.
419     }
420 
421     //! finds the currently valid representation for the handle \a h
422     //! and returns a pointer to its stored value of type \a T.
423     template <class H>
424     static typename H::Rep_pointer find( const H& h) {
425         return h.ptr_->base_ptr();
426     }
427 };
428 
429 /*!\brief
430  * Policy class for \c Handle_with_policy that implements unifying of
431  * identical representations \c T with trees and path compression, is a
432  * model of the \c HandlePolicy concept.
433  */
434 class Handle_policy_union {
435 public:
436     /*!\brief
437      * A rebind mechanism to create the representation type.
438      */
439     template <class T, int hierarchy>
440     struct Rep_bind {
441         //! this default constructor contains some compile-time checks.
442         Rep_bind() {
443           //Intern::Rep_bind_reference_counted_with_forwarding<T, hierarchy>
444           //     check;
445           //  (void)check;
446           (void)Intern::Rep_bind_reference_counted_with_forwarding<T, hierarchy>();
447         }
448         //! the representation type including a reference counter.
449         //! The handle allocates objects of this type.
450         typedef typename Intern::Rep_bind_reference_counted_with_forwarding<T,
451             hierarchy>::Rep Rep;
452     };
453 
454     /*!\brief
455      * A rebind mechanism to access the base class for class hierarchies
456      * of representations.
457      *
458      * The base classes can be used directly, but this
459      * rebind mechamism allows the implementation of handle-rep classes
460      * that are parameterized with the policy class only and adapt to
461      * the necessary base class.
462      */
463     template <class Alloc>
464     struct Hierarchy_base {
465         //! type that can be used as base class for the representation type.
466         typedef Reference_counted_hierarchy_with_union<Alloc> Type;
467     };
468 
469     /*! \brief unifies the representations of the two handles \a h and \a g.
470         Performs union.
471         \pre The representations represent the same value and one can be
472         replaced by the other. The handles \a h and \a g are already
473         the representatives found by the find operation and \a h is not
474         equal to \a g. The tree representing the union of \a h has size
475         not smaller than the corresponding tree size of \a g.
476     */
477     template <class H>
478     static void unify_large_small( const H& h, const H& g) {
479         typename H::Rep* hrep = h.ptr_;
480         typename H::Rep* grep = g.ptr_;
481         CGAL_precondition( ! grep->is_forwarding());
482         CGAL_precondition( hrep->union_size() >= grep->union_size());
483         grep->add_union_size(-1);
484         // make g point to h's rep.
485         if ( grep->is_shared()) {
486             // grep survises the loss of one reference
487             // and hrep gets one more reference
488             grep->remove_reference();
489             hrep->add_reference();
490             hrep->add_union_size( grep->union_size());
491             grep->next = hrep;
492         } else {
493             g.delete_rep( grep); // did not survive loss of handle g
494         }
495         // redirect handle g and incr. hrep's counter
496         g.ptr_ = hrep;
497         hrep->add_reference();
498         hrep->add_union_size(1);
499     }
500 
501     /*! \brief unifies the representations of the two handles \a h and \a g.
502         Performs union with path compression.
503         \pre The representations represent the same value and one can be
504         replaced by the other.
505     */
506     template <class H>
507     static void unify( const H& h, const H& g) {
508         if ( find(h) !=  find(g)) {
509             if ( h.ptr_->union_size() > g.ptr_->union_size())
510                 unify_large_small( h, g); // make g point to h's rep.
511             else
512                 unify_large_small( g, h); // make h point to g's rep.
513         }
514     }
515 
516     /*! \brief finds the currently valid representation for the handle \a h
517         and returns a pointer to its stored value of type \a T. Performs
518         path-compression to speed-up later union operations.
519     */
520     template <class H>
521     static typename H::Rep_pointer find( const H& h) {
522         typedef typename H::Rep Rep;
523         if ( h.ptr_->is_forwarding()) {
524             // find new valid representation
525             Rep* new_rep = h.ptr_;
526             while ( new_rep->next != 0)
527                 new_rep = static_cast<Rep*>(new_rep->next);
528             // path compression: assign new rep to all reps seen on the path
529             // update reference count properly: all reps on the path lose
530             // one reference, and the new_rep gains all of them unless
531             // the rep on the path get actually deleted.
532             Rep* rep = h.ptr_;
533             while ( rep != new_rep) {
534                 Rep* tmp = static_cast<Rep*>(rep->next);
535                 if ( rep->is_shared()) {
536                     // rep survives the loss of one reference
537                     // and new_rep gets one more reference
538                     rep->remove_reference();
539                     if ( tmp != new_rep) {
540                         // re-link rep to the new_rep
541                         rep->next = new_rep;
542                         new_rep->add_reference();
543                     }
544                 } else {
545                     h.delete_rep( rep); // we have to delete the current rep
546                     tmp->remove_reference();
547                 }
548                 rep = tmp;
549             }
550             // hook h to new_rep
551             h.ptr_ = new_rep;
552             new_rep->add_reference();
553         }
554         return h.ptr_->base_ptr();
555     }
556 };
557 
558 /*!\brief Policy class for \c Handle_with_policy that implements unifying of
559  * identical representations \c T with trees and path compression.
560  *
561  * It also
562  * sets the unused representation immediately to the default constructed
563  * representation \c T(), which can help to free memory if the
564  * representation is dynamically allocated and potentially large, e.g.,
565  * \c leda::real. This class is a model of the \c HandlePolicy concept.
566  */
567 class Handle_policy_union_and_reset {
568 public:
569     /*!\brief
570      * A rebind mechanism to create the representation type.
571      */
572     template <class T, int hierarchy>
573     struct Rep_bind {
574         //! this default constructor contains some compile-time checks.
575         Rep_bind() {
576           //Intern::Rep_bind_reference_counted_with_forwarding<T, hierarchy>
577           //     check;
578           // (void)check;
579           (void)Intern::Rep_bind_reference_counted_with_forwarding<T, hierarchy>();
580         }
581         //! the representation type including a reference counter.
582         //! The handle allocates objects of this type.
583         typedef typename Intern::Rep_bind_reference_counted_with_forwarding<T,
584             hierarchy>::Rep Rep;
585     };
586 
587     /*!\brief
588      * A rebind mechanism to access the base class for class hierarchies
589      * of representations.
590      *
591      * The base classes can be used directly, but this
592      * rebind mechamism allows the implementation of handle-rep classes
593      * that are parameterized with the policy class only and adapt to
594      * the necessary base class.
595      */
596     template <class Alloc>
597     struct Hierarchy_base {
598         //! type that can be used as base class for the representation type.
599         typedef Reference_counted_hierarchy_with_union<Alloc> Type;
600     };
601 
602     // abbreviation to re-use its implementation below.
603     typedef Handle_policy_union U;
604 
605     /*! \brief unifies the representations of the two handles \a h and \a g.
606         Performs union with path compression and assigns a default
607         constructed value of the representation type \c Rep to the
608         superfluous representation.
609         \pre The representations represent the same value and one can be
610         replaced by the other.
611     */
612     template <class H>
613     static void unify( const H& h, const H& g) {
614         if ( find(h) !=  find(g)) {
615             if ( h.ptr_->union_size() > g.ptr_->union_size()) {
616                 // reset representation in g to default construction of T
617                 if ( g.ptr_->is_shared())
618                     g.ptr_->clear();
619                 U::unify_large_small( h, g); // make g point to h's rep.
620             } else {
621                 // reset representation in h to default construction of T
622                 if ( h.ptr_->is_shared())
623                     h.ptr_->clear();
624                 U::unify_large_small( g, h); // make h point to g's rep.
625             }
626         }
627     }
628 
629     /*! \brief finds the currently valid representation for the handle \a h
630         and returns a pointer to its stored value of type \a T. Performs
631         path-compression to speed-up later union operations.
632     */
633     template <class H>
634     static typename H::Rep_pointer find( const H& h) { return U::find(h); }
635 };
636 
637 
638 /*! \brief the base class for handles of reference counted representations of
639     \c T.
640 
641     There are two fundamentally different usages of this base class:
642 
643         - with a single representation class. In this case the handle
644           manages allocation and deallocation and the type \c T can
645           be an arbitrary type---the handle adds the necessary reference
646           counter internally.
647 
648         - with a hierarchy of representation classes. Type \c T will be
649           the common base class of this hierarchy and it has to be derived
650           itself from either \c ::CGAL::Reference_counted_hierarchy or
651           \c ::CGAL::Reference_counted_hierarchy_with_union, both parameterized
652           with an allocator. The allocator in the handle will not be used in
653           this scenario, since the handle class does not allocate any
654           representations. Instead, the handle class derived from this handle
655           base class is allocating the different representations with the
656           \c new operator. In this case, the allocator in the base class
657           of \c T is used.
658 
659     The handle class distinguishes between these two alternative
660     usages by checking if \c T is derived from one of the two base
661     classes mentioned for the second alternative. If not, it picks the
662     first alternative.
663 
664     In the second alternative, the correct base class, \c
665     ::CGAL::Reference_counted_hierarchy_with_union, has to be used
666     if the policy class is one of \c class Handle_policy_union r \c
667     Handle_policy_union_and_reset. Otherwise, the other base class can
668     be used to save space.
669 
670     The policy class \c Handle_policy_in_place is incompatible with the class
671     hierarchy for representation classes since the pointer in the
672     handle class would be missing.
673 
674     The dependency of the base classes for \c T and the policy classes
675     is also encoded in the policy classes and can be used to write
676     generic handle-rep scheme classes. To do that one can derive \c T
677     from the expressions \c Policy::Hierarchy_base<Alloc>::Type
678     assuming that \c Policy is the handle policy and \c Alloc is the
679     allocator. Btw, the allocator is used as an allocator of character
680     arrays here.
681 
682     \see \link Handle Handle for Reference Counting\endlink for
683     an example for each of the two alternative usages.
684 
685     The template parameters are:
686         - \b T: is one of the two following:
687             - an arbitrary type but it must be a model of the
688               \c DefaultConstructible concept if the default constructor
689               of the handle is used.
690             - a type derived from \c Reference_counted_hierarchy<Alloc> or
691               \c Reference_counted_hierarchy_with_union<Alloc> implementing
692               their virtual member function interface, namely a \c clone()
693               function.
694 
695         - \b HandlePolicy: a model of the \c HandlePolicy concept or the
696               \c Handle_policy_in_place class template that selects a specialized
697               implementation without reference counting. Has the
698               default \c Handle_policy_no_union.
699 
700         - \b Allocator_: a model of the \c Allocator concept,
701           has the default \c CGAL_ALLOCATOR(T).
702 
703 */
704 template <class T_,
705           class HandlePolicy = Handle_policy_no_union,
706           class Allocator_ = CGAL_ALLOCATOR(T_)>
707 class Handle_with_policy {
708 public:
709 
710     //! first template parameter
711     typedef T_ Handled_type;
712 
713     //! the handle type itself.
714     typedef Handle_with_policy< Handled_type, HandlePolicy, Allocator_>    Self;
715 
716     //! the instantiated model of the \c HandlePolicy concept.
717     typedef HandlePolicy                Handle_policy;
718 
719     //! the allocator type.
720     typedef Allocator_                  Allocator;
721 
722     enum { is_class_hierarchy  =
723         ::CGAL::is_same_or_derived< Reference_counted_hierarchy_base, Handled_type>::value };
724 
725     typedef typename Handle_policy::template Rep_bind< Handled_type, is_class_hierarchy > Bind;
726 
727     // instantiate Rep_bind to activate compile time check in there
728     static Bind bind;
729 
730     // Define type that is used for function matching
731     typedef typename ::boost::mpl::if_c<
732          is_class_hierarchy,
733            ::CGAL::Tag_true,
734            ::CGAL::Tag_false >::type
735          Class_hierarchy;
736 
737     //! the internal representation, i.e., \c T plus a reference count
738     //! (if needed), or just \c T if we derived from the base class to
739     //! support a class hierarchy for the representations.
740     typedef typename Bind::Rep  Rep;
741 
742     typedef typename Rep::Rep_pointer  Rep_pointer;
743 
744     typedef std::allocator_traits<Allocator_> Allocator_traits;
745     typedef typename Allocator_traits::template rebind_alloc<Rep> Rep_allocator;
746 
747     //! integer type for identifying a representation.
748     typedef std::ptrdiff_t              Id_type;
749 
750     friend class Handle_policy_no_union;
751     friend class Handle_policy_union;
752     friend class Handle_policy_union_and_reset;
753 private:
754     mutable Rep*  ptr_;
755 
756     // We have to distinguish between allocating single representations
757     // and where we have a class hierarchy of representations, where the
758     // user is responsible for allocating the first representations
759     // and we can just \c clone and delete them.
760     static Rep_allocator allocator;
761 
762     static Rep* new_rep( const Rep& rep) {
763         CGAL_static_assertion( !(
764            ::CGAL::is_same_or_derived< Reference_counted_hierarchy_base, Handled_type >::value ));
765         Rep* p = allocator.allocate(1);
766         std::allocator_traits<Rep_allocator>::construct(allocator, p, rep);
767         return p;
768     }
769     static void delete_rep( Rep* p, ::CGAL::Tag_false ) {
770       std::allocator_traits<Rep_allocator>::destroy(allocator, p);
771         allocator.deallocate( p, 1);
772     }
773     static void delete_rep( Rep* p, ::CGAL::Tag_true ) {
774         delete p;
775     }
776     static void delete_rep( Rep* p) { delete_rep(p, Class_hierarchy()); }
777 
778     static Rep* clone_rep( Rep* p, ::CGAL::Tag_false ) {
779         return new_rep( *p);
780     }
781     static Rep* clone_rep( Rep* p, ::CGAL::Tag_true ) {
782         return static_cast<Rep*>(p->clone());
783     }
784     static Rep* clone_rep( Rep* p) { return clone_rep( p, Class_hierarchy()); }
785 
786     void remove_reference() {
787         // cleans up the possible chain of forwarding reps
788         Handle_policy::find( *this);
789         if ( ! is_shared()) {
790             delete_rep( ptr_);
791         } else {
792             ptr_->remove_reference();
793             ptr_->add_union_size( -1);
794         }
795     }
796 
797     template <class TT>
798     Rep* make_from_single_arg( const TT& t, ::CGAL::Tag_false ) {
799         return new_rep( Rep( Handled_type(t)));
800     }
801     template <class TT>
802     Rep* make_from_single_arg( TT t, ::CGAL::Tag_true ) {
803       //Bind bind_; // trigger compile-time check
804       // (void)bind_;
805       (void)Bind(); // shouldn't this be enough to trigger?
806         return t; // has to be a pointer convertible to Rep*
807     }
808 
809 protected:
810     //! protected access to the stored representation
811     Handled_type*       ptr()       { return static_cast<Handled_type*>(Handle_policy::find(*this));}
812     //! protected access to the stored representation
813     const Handled_type* ptr() const {
814         return static_cast<const Handled_type*>(Handle_policy::find( *this));
815     }
816 
817     //! unify two representations. \pre The two representations describe
818     //! the same value  and one can be replaced by the other, i.e., the
819     //! values are immutable, or protected from changes with \c copy_on_write()
820     //! calls!
821     void unify( const Self& h) const { Handle_policy::unify( *this, h); }
822 
823     //! can be called before modifying a shared representation
824     //! to get an own copy of the representation which avoids effecting the
825     //! other sharing handles. Does nothing if representation is actually
826     //! not shared.
827     void copy_on_write() {
828         Handle_policy::find( *this);
829         if ( is_shared() ) {
830             Rep* tmp_ptr = clone_rep( ptr_);
831             ptr_->remove_reference();
832             ptr_->add_union_size( -1);
833             ptr_ = tmp_ptr;
834         }
835     }
836 
837     //! used with special protected constructor
838     enum Use_with_initialize_with {
839         USE_WITH_INITIALIZE_WITH //!< used with special protected constructor
840                                  //!< of \c Handle_with_policy.
841     };
842 
843     //! special constructor, postpones the construction of the representation
844     //! to one of the \c initialize_with() functions. An object is in an
845     //! invalid state (and will report a failed precondition later) if
846     //! it is not initialized with an \c initialize_with() function call
847     //! after this constructor. Applicable for single representation but
848     //! also for a class hierarchy of representations.
849     Handle_with_policy( Use_with_initialize_with) : ptr_( 0) {}
850 
851     //! constructor used for class hierarchies of representations, where
852     //! the handle class derived from this handle creates the different
853     //! representations itself with the \c new operator. Except for this
854     //! constructor, the one with the \c Use_with_initialize_with
855     //! argument, and the single argument template constructor no other
856     //! constructor will work for class hierarchies of representations.
857     Handle_with_policy( Rep* p) : ptr_( p) {
858         CGAL_static_assertion((
859            ::CGAL::is_same_or_derived< Reference_counted_hierarchy_base, Handled_type >::value ));
860         //Bind bind_; // trigger compile-time check
861         //(void)bind_;
862         (void)Bind();
863     }
864 
865     //! initializes the representation after the constructor from
866     //! \c USE_WITH_INITIALIZE_WITH has been used. Applicable for a
867     //! class hierarchy of representations only, where the derived handle class
868     //! created the representation \c p with the \c new operator. No other
869     //! version of \c initialize_with is applicable in this case except
870     //! the template version with one argument.
871     void initialize_with( Rep* p) {
872         CGAL_static_assertion((
873            ::CGAL::is_same_or_derived< Reference_counted_hierarchy_base, Handled_type >::value ));
874         //Bind bind_; // trigger compile-time check
875         //(void)bind_;
876         (void)Bind();
877         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
878                          "representation has already been initialized.");
879         ptr_ = p;
880     }
881 
882     //! initializes the representation after the constructor from
883     //! \c USE_WITH_INITIALIZE_WITH has been used.
884     //! In case of the class hierarchy of representation classes,
885     //! this function is also chosen for pointers to newly allocated
886     //! representations that are types derived from \c T. In that case,
887     //! the pointer is just assigned to the internal pointer.
888     template <class T1>
889     void initialize_with( const T1& t1) {
890         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
891                          "representation has already been initialized.");
892         ptr_ = make_from_single_arg( t1, Class_hierarchy());
893     }
894 
895     //! initializes the representation after the constructor from
896     //! \c USE_WITH_INITIALIZE_WITH has been used.
897     template <class T1, class T2>
898     void initialize_with( const T1& t1, const T2& t2) {
899         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
900                          "representation has already been initialized.");
901         ptr_ = new_rep( Rep( Handled_type(t1,t2)));
902     }
903 
904     //! initializes the representation after the constructor from
905     //! \c USE_WITH_INITIALIZE_WITH has been used.
906     template <class T1, class T2, class T3>
907     void initialize_with( const T1& t1, const T2& t2, const T3& t3) {
908         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
909                          "representation has already been initialized.");
910         ptr_ = new_rep( Rep( Handled_type(t1,t2,t3)));
911     }
912 
913     //! initializes the representation after the constructor from
914     //! \c USE_WITH_INITIALIZE_WITH has been used.
915     template <class T1, class T2, class T3, class T4>
916     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
917                           const T4& t4) {
918         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
919                          "representation has already been initialized.");
920         ptr_ = new_rep( Rep( Handled_type(t1,t2,t3,t4)));
921     }
922 
923     //! initializes the representation after the constructor from
924     //! \c USE_WITH_INITIALIZE_WITH has been used.
925     template <class T1, class T2, class T3, class T4, class T5>
926     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
927                           const T4& t4, const T5& t5) {
928         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
929                          "representation has already been initialized.");
930         ptr_ = new_rep( Rep( Handled_type(t1,t2,t3,t4,t5)));
931     }
932 
933     //! initializes the representation after the constructor from
934     //! \c USE_WITH_INITIALIZE_WITH has been used.
935     template <class T1, class T2, class T3, class T4, class T5, class T6>
936     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
937                           const T4& t4, const T5& t5, const T6& t6) {
938         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
939                          "representation has already been initialized.");
940         ptr_ = new_rep( Rep( Handled_type(t1,t2,t3,t4,t5,t6)));
941     }
942 
943     //! initializes the representation after the constructor from
944     //! \c USE_WITH_INITIALIZE_WITH has been used.
945     template <class T1, class T2, class T3, class T4, class T5, class T6,
946               class T7>
947     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
948                           const T4& t4, const T5& t5, const T6& t6,
949                           const T7& t7) {
950         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
951                          "representation has already been initialized.");
952         ptr_ = new_rep( Rep( Handled_type(t1,t2,t3,t4,t5,t6,t7)));
953     }
954 
955     //! initializes the representation after the constructor from
956     //! \c USE_WITH_INITIALIZE_WITH has been used.
957     template <class T1, class T2, class T3, class T4, class T5, class T6,
958               class T7, class T8>
959     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
960                           const T4& t4, const T5& t5, const T6& t6,
961                           const T7& t7, const T8& t8) {
962         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
963                          "representation has already been initialized.");
964         ptr_ = new_rep( Rep( Handled_type(t1,t2,t3,t4,t5,t6,t7,t8)));
965     }
966 
967     //! initializes the representation after the constructor from
968     //! \c USE_WITH_INITIALIZE_WITH has been used.
969     template <class T1, class T2, class T3, class T4, class T5, class T6,
970               class T7, class T8, class T9>
971     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
972                           const T4& t4, const T5& t5, const T6& t6,
973                           const T7& t7, const T8& t8, const T9& t9) {
974         CGAL_precondition_msg( ptr_ == 0, "Handle_with_policy::initialize_with(): the "
975                          "representation has already been initialized.");
976         ptr_ = new_rep( Rep( Handled_type(t1,t2,t3,t4,t5,t6,t7,t8,t9)));
977     }
978 
979 public:
980     //! default constructor.
981     Handle_with_policy() : ptr_( new_rep( Rep())) {}
982 
983     //! copy constructor, increments reference count.
984     Handle_with_policy(const Self& h) {
985         CGAL_precondition_msg( h.ptr_ != 0, "Handle_with_policy::Handle_with_policy( Self): probably "
986                          "used special protected constructor and not the "
987                          "'initialize_with()' function.");
988         Handle_policy::find( h);
989         ptr_ = h.ptr_;
990         ptr_->add_reference();
991         ptr_->add_union_size( 1);
992     }
993 
994     //! forwarding constructor passing its parameter to the representation
995     //! constructor. In case of the class hierarchy of representation classes,
996     //! this constructor is also chosen for pointers to newly allocated
997     //! representations that are types derived from \c T. In that case,
998     //! the pointer is just assigned to the internal pointer.
999     template <class T1>
1000     explicit Handle_with_policy( const T1& t)
1001         : ptr_( make_from_single_arg( t, Class_hierarchy())) {}
1002 
1003     //! forwarding constructor passing its parameters to the representation
1004     //! constructor.
1005     template <class T1, class T2>
1006     Handle_with_policy( const T1& t1, const T2& t2) : ptr_( new_rep( Rep( Handled_type( t1, t2)))) {}
1007 
1008     //! forwarding constructor passing its parameters to the representation
1009     //! constructor.
1010     template <class T1, class T2, class T3>
1011     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3)
1012         : ptr_( new_rep( Rep( Handled_type( t1, t2, t3)))) {}
1013 
1014     //! forwarding constructor passing its parameters to the representation
1015     //! constructor.
1016     template <class T1, class T2, class T3, class T4>
1017     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4)
1018         : ptr_( new_rep( Rep( Handled_type( t1, t2, t3, t4)))) {}
1019 
1020     //! forwarding constructor passing its parameters to the representation
1021     //! constructor.
1022     template <class T1, class T2, class T3, class T4, class T5>
1023     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1024             const T5& t5)
1025         : ptr_( new_rep( Rep( Handled_type( t1, t2, t3, t4, t5)))) {}
1026 
1027     //! forwarding constructor passing its parameters to the representation
1028     //! constructor.
1029     template <class T1, class T2, class T3, class T4, class T5, class T6>
1030     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1031             const T5& t5, const T6& t6)
1032         : ptr_( new_rep( Rep( Handled_type( t1, t2, t3, t4, t5, t6)))) {}
1033 
1034     //! forwarding constructor passing its parameters to the representation
1035     //! constructor.
1036     template <class T1, class T2, class T3, class T4, class T5, class T6,
1037               class T7>
1038     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1039             const T5& t5, const T6& t6, const T7& t7)
1040         : ptr_( new_rep( Rep( Handled_type( t1, t2, t3, t4, t5, t6, t7)))) {}
1041 
1042     //! forwarding constructor passing its parameters to the representation
1043     //! constructor.
1044     template <class T1, class T2, class T3, class T4, class T5, class T6,
1045               class T7, class T8>
1046     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1047             const T5& t5, const T6& t6, const T7& t7, const T8& t8)
1048         : ptr_( new_rep( Rep( Handled_type( t1, t2, t3, t4, t5, t6, t7, t8)))) {}
1049 
1050     //! forwarding constructor passing its parameters to the representation
1051     //! constructor.
1052     template <class T1, class T2, class T3, class T4, class T5, class T6,
1053               class T7, class T8, class T9>
1054     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1055             const T5& t5, const T6& t6, const T7& t7, const T8& t8,
1056             const T9& t9)
1057         : ptr_( new_rep( Rep( Handled_type( t1, t2, t3, t4, t5, t6, t7, t8, t9)))) {}
1058 
1059     //! destructor, decrements reference count.
1060     ~Handle_with_policy() {
1061       //Bind bind_; // trigger compile-time check
1062       //(void)bind_;
1063       (void)Bind();
1064         CGAL_precondition_msg( ptr_ != 0, "Handle_with_policy::~Handle_with_policy(): probably used "
1065                          "special protected constructor and not the "
1066                          "'initialize_with()' function.");
1067         remove_reference();
1068     }
1069 
1070     //! assignment, updates reference count correspondingly.
1071     Self& operator=( const Self& h) {
1072         CGAL_precondition_msg( h.ptr_ != 0, "Handle_with_policy::operator=(): probably "
1073                          "used special protected constructor and not the "
1074                          "'initialize_with()' function.");
1075         Handle_policy::find( h);
1076         h.ptr_->add_reference();
1077         h.ptr_->add_union_size( 1);
1078         remove_reference();
1079         ptr_ = h.ptr_;
1080         return *this;
1081     }
1082 
1083     //! returns \c true if both share the same representation.
1084     bool is_identical( const Self& h) const { return ptr() == h.ptr(); }
1085 
1086     //! returns a unique id value. Two handles share their representation
1087     //! is their id values are identical.
1088     Id_type id() const { return reinterpret_cast<Id_type>(&*ptr()); }
1089 
1090     //! returns true if the representation is shared, i.e., the reference
1091     //! counter is greater than one.
1092     bool is_shared() const { return ptr_->is_shared(); }
1093 
1094     //! returns \c true if the representation is actually forwarding to
1095     //! another equivalent representation (happens only with the
1096     //! union-find policies).
1097     bool is_forwarding() const { return ptr_->is_forwarding(); }
1098 
1099     //! returns the size of the union set including all reference counts that
1100     //! have been accumulated so far for this representation.
1101     int  union_size() const { return ptr_->union_size(); }
1102 
1103     // backwards compatible
1104     bool identical( const Self& h) const { return is_identical(h); }
1105 
1106 #ifdef CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST
1107     // provide access to pointer for testing only!!
1108     const Rep* test_ptr() const { return ptr_; }
1109     // provide access to pointer for testing only!!
1110     bool test_identical_ptr( const Self& h) const { return ptr_ == h.ptr_; }
1111 #endif // CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST
1112 };
1113 
1114 // instantiate Rep_bind to activate compile time check in there
1115 template <class T, class Policy, class Alloc>
1116 typename Handle_with_policy<T,Policy,Alloc>::Bind Handle_with_policy<T,Policy,Alloc>::bind;
1117 
1118 
1119 //! alternative syntax for \c h.id() to allow use with LEDA
1120 /*! This is only provided for \c Handle_policy_no_union because
1121  *  ID numbers have to be fixed throughout an object's lifetime.
1122  */
1123 template <class T, class A>
1124 typename Handle_with_policy<T, Handle_policy_no_union, A>::Id_type
1125 ID_Number(const Handle_with_policy<T, Handle_policy_no_union, A>& h)
1126     { return h.id(); }
1127 
1128 template <class T, class Policy, class Alloc>
1129 typename Handle_with_policy<T, Policy, Alloc>::Rep_allocator
1130     Handle_with_policy<T, Policy, Alloc>::allocator;
1131 
1132 
1133 /*! \brief specialization of the base class for handles for non-reference
1134     counted representations.
1135     Uses \c LEDA_MEMORY if available.
1136 */
1137 template <class T_, class Allocator_>
1138 class Handle_with_policy<T_, Handle_policy_in_place, Allocator_> {
1139 public:
1140 
1141     //! first template paramter
1142     typedef T_ Handled_type;
1143 
1144     //! the handle type itself.
1145     typedef Handle_with_policy< Handled_type, Handle_policy_in_place, Allocator_>   Self;
1146 
1147     //! the model of the \c HandlePolicy concept.
1148     typedef Handle_policy_in_place                           Handle_policy;
1149 
1150     //! the allocator type.
1151     typedef Allocator_                                Allocator;
1152 
1153     //! identify \c T with the internal representation \c Rep.
1154     typedef Handled_type                              Rep;
1155 
1156     //! integer type for identifying a representation.
1157     typedef std::ptrdiff_t                            Id_type;
1158 private:
1159     // store the rep in place
1160     Rep  rep;
1161 
1162 protected:
1163     //! protected access to the stored representation
1164     Handled_type*       ptr()       { return &rep; }
1165     //! protected access to the stored representation
1166     const Handled_type* ptr() const { return &rep; }
1167 
1168     //! unify two representations, a null op here.
1169     void unify( const Self&) const {}
1170 
1171     //! can be called before modifying a shared representation
1172     //! to get an own copy of the representation, a null op here.
1173     void copy_on_write() {}
1174 
1175     //! used with special protected constructor
1176     enum Use_with_initialize_with {
1177         USE_WITH_INITIALIZE_WITH //!< used with special protected constructor
1178     };
1179 
1180     //! special constructor, postpones the construction of the representation
1181     //! to one of the \c initialize_with() functions. Requires default
1182     //! constructor for \c T.
1183     Handle_with_policy( Use_with_initialize_with) {}
1184 
1185     //! initializes the representation after the constructor from
1186     //! \c USE_WITH_INITIALIZE_WITH has been used.
1187     template <class T1>
1188     void initialize_with( const T1& t1) { rep = Rep(t1); }
1189 
1190     //! initializes the representation after the constructor from
1191     //! \c USE_WITH_INITIALIZE_WITH has been used.
1192     template <class T1, class T2>
1193     void initialize_with( const T1& t1, const T2& t2) { rep = Rep(t1,t2); }
1194 
1195     //! initializes the representation after the constructor from
1196     //! \c USE_WITH_INITIALIZE_WITH has been used.
1197     template <class T1, class T2, class T3>
1198     void initialize_with( const T1& t1, const T2& t2, const T3& t3) {
1199         rep = Rep(t1,t2,t3);
1200     }
1201 
1202     //! initializes the representation after the constructor from
1203     //! \c USE_WITH_INITIALIZE_WITH has been used.
1204     template <class T1, class T2, class T3, class T4>
1205     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
1206                           const T4& t4) {
1207         rep = Rep(t1,t2,t3,t4);
1208     }
1209 
1210     //! initializes the representation after the constructor from
1211     //! \c USE_WITH_INITIALIZE_WITH has been used.
1212     template <class T1, class T2, class T3, class T4, class T5>
1213     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
1214                           const T4& t4, const T5& t5) {
1215         rep = Rep(t1,t2,t3,t4,t5);
1216     }
1217 
1218     //! initializes the representation after the constructor from
1219     //! \c USE_WITH_INITIALIZE_WITH has been used.
1220     template <class T1, class T2, class T3, class T4, class T5, class T6>
1221     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
1222                           const T4& t4, const T5& t5, const T6& t6) {
1223         rep = Rep(t1,t2,t3,t4,t5,t6);
1224     }
1225 
1226     //! initializes the representation after the constructor from
1227     //! \c USE_WITH_INITIALIZE_WITH has been used.
1228     template <class T1, class T2, class T3, class T4, class T5, class T6,
1229               class T7>
1230     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
1231                           const T4& t4, const T5& t5, const T6& t6,
1232                           const T7& t7) {
1233         rep = Rep(t1,t2,t3,t4,t5,t6,t7);
1234     }
1235 
1236     //! initializes the representation after the constructor from
1237     //! \c USE_WITH_INITIALIZE_WITH has been used.
1238     template <class T1, class T2, class T3, class T4, class T5, class T6,
1239               class T7, class T8>
1240     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
1241                           const T4& t4, const T5& t5, const T6& t6,
1242                           const T7& t7, const T8& t8) {
1243         rep = Rep(t1,t2,t3,t4,t5,t6,t7,t8);
1244     }
1245 
1246     //! initializes the representation after the constructor from
1247     //! \c USE_WITH_INITIALIZE_WITH has been used.
1248     template <class T1, class T2, class T3, class T4, class T5, class T6,
1249               class T7, class T8, class T9>
1250     void initialize_with( const T1& t1, const T2& t2, const T3& t3,
1251                           const T4& t4, const T5& t5, const T6& t6,
1252                           const T7& t7, const T8& t8, const T9& t9) {
1253         rep = Rep(t1,t2,t3,t4,t5,t6,t7,t8,t9);
1254     }
1255 
1256 public:
1257     //! default constructor.
1258     Handle_with_policy() {}
1259 
1260     //! copy constructor.
1261     Handle_with_policy(const Self& h) : rep( h.rep) {}
1262 
1263     //! forwarding constructor passing its parameter to the representation
1264     //! constructor.
1265     template <class T1>
1266     explicit Handle_with_policy( const T1& t) : rep( Rep(t)) {}
1267 
1268     //! forwarding constructor passing its parameters to the representation
1269     //! constructor.
1270     template <class T1, class T2>
1271     Handle_with_policy( const T1& t1, const T2& t2) : rep( Rep(t1,t2)) {}
1272 
1273     //! forwarding constructor passing its parameters to the representation
1274     //! constructor.
1275     template <class T1, class T2, class T3>
1276     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3) : rep( Rep(t1,t2,t3)) {}
1277 
1278     //! forwarding constructor passing its parameters to the representation
1279     //! constructor.
1280     template <class T1, class T2, class T3, class T4>
1281     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4)
1282         : rep( Rep( t1, t2, t3, t4)) {}
1283 
1284     //! forwarding constructor passing its parameters to the representation
1285     //! constructor.
1286     template <class T1, class T2, class T3, class T4, class T5>
1287     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1288             const T5& t5)
1289         : rep( Rep( t1, t2, t3, t4, t5)) {}
1290 
1291     //! forwarding constructor passing its parameters to the representation
1292     //! constructor.
1293     template <class T1, class T2, class T3, class T4, class T5, class T6>
1294     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1295             const T5& t5, const T6& t6)
1296         : rep( Rep( t1, t2, t3, t4, t5, t6)) {}
1297 
1298     //! forwarding constructor passing its parameters to the representation
1299     //! constructor.
1300     template <class T1, class T2, class T3, class T4, class T5, class T6,
1301               class T7>
1302     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1303             const T5& t5, const T6& t6, const T7& t7)
1304         : rep( Rep( t1, t2, t3, t4, t5, t6, t7)) {}
1305 
1306     //! forwarding constructor passing its parameters to the representation
1307     //! constructor.
1308     template <class T1, class T2, class T3, class T4, class T5, class T6,
1309               class T7, class T8>
1310     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1311             const T5& t5, const T6& t6, const T7& t7, const T8& t8)
1312         : rep( Rep( t1, t2, t3, t4, t5, t6, t7, t8)) {}
1313 
1314     //! forwarding constructor passing its parameters to the representation
1315     //! constructor.
1316     template <class T1, class T2, class T3, class T4, class T5, class T6,
1317               class T7, class T8, class T9>
1318     Handle_with_policy( const T1& t1, const T2& t2, const T3& t3, const T4& t4,
1319             const T5& t5, const T6& t6, const T7& t7, const T8& t8,
1320             const T9& t9)
1321         : rep( Rep( t1, t2, t3, t4, t5, t6, t7, t8, t9)) {}
1322 
1323     //! returns \c true if both share the same representation.
1324     bool is_identical( const Self& h) const { return this == &h; }
1325 
1326     //! returns a unique id value. Two handles share their representation
1327     //! is their id values are identical.
1328     Id_type id() const { return ptr() - static_cast<Handled_type const*>(0); }
1329 
1330     //! returns \c false since the representation is not shared for
1331     //! this specialization.
1332     bool is_shared() const { return false; }
1333 
1334     //! returns \c false since the representation is not forwarding for
1335     //! this specialization.
1336     bool is_forwarding() const { return false; }
1337 
1338     //! returns \c 1 as the union size for this specialization.
1339     int  union_size() const { return 1; }
1340 
1341     // backwards compatible
1342     bool identical( const Self& h) const { return is_identical(h); }
1343 
1344 #ifdef CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST
1345     // provide access to pointer for testing only!!
1346     const Rep* test_ptr() const { return *rep; }
1347     // provide access to pointer for testing only!!
1348     bool test_identical_ptr( const Self& h) const { return this == &h; }
1349 #endif // CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST
1350 
1351 #ifdef CGAL_USE_LEDA
1352     LEDA_MEMORY( Self)
1353 #endif
1354 };
1355 
1356 template <class T, class HandlePolicy, class Allocator>
1357 inline bool identical(const Handle_with_policy<T,HandlePolicy,Allocator> &h1, const Handle_with_policy<T,HandlePolicy,Allocator> &h2) { return h1.is_identical(h2); }
1358 
1359 
1360 /*\brief
1361  * This class' function call operator test whether one handle's \c id is
1362  * less than the \c id of the other handle.
1363  *
1364  * "Less" is defined in terms of the second template argument,
1365  * which defaults to \c std::less<Handle::Id_type>
1366  */
1367 template <class Handle, class Less = std::less<typename Handle::Id_type> >
1368 class Handle_id_less_than {
1369 public:
1370     //! result_type
1371     typedef bool result_type;
1372     //! type of first argument
1373     typedef Handle first_argument_type;
1374     //! type of second argument
1375     typedef Handle second_argument_type;
1376     //! returns \c true iff \c h1.id() < \c h2.id()
1377     bool operator () (Handle h1, Handle h2) {
1378         Less is_less;
1379         return is_less(h1.id(), h2.id());
1380     }
1381     //! returns \c true iff \c h1.id() < \c h2.id()
1382     bool operator () (Handle h1, Handle h2) const {
1383         Less is_less;
1384         return is_less(h1.id(), h2.id());
1385     }
1386 };
1387 
1388 
1389 //@}
1390 
1391 } //namespace CGAL
1392 
1393 #endif // CGAL_HANDLE_WITH_POLICY_H
1394