// ============================================================================ // // This software and related documentation is part of an INTERNAL release // of the Computational Geometry Algorithms Library (CGAL). It is not // intended for general use. // // ---------------------------------------------------------------------------- // $URL$ // $Id$ // Author(s) : Michael Seel // Arno Eigenwillig // Lutz Kettner // // ============================================================================ #define CGAL_HANDLE_WITH_POLICY_INTERNAL_TEST #include #include #include #include struct Int_rep { int val; Int_rep( int i = 0) : val(i) {} Int_rep( int i, int j) : val(i+j) {} Int_rep( int i, int j, int k) : val(i+j+k) {} }; template < class Unify> struct Int_t : public ::CGAL::Handle_with_policy< Int_rep, Unify > { typedef ::CGAL::Handle_with_policy< Int_rep, Unify > Base; Int_t( int i = 0) : Base( i) {} Int_t( int i, int j) : Base( i, j) {} // test template constructors Int_t( int i, int j, int k) : Base( Base::USE_WITH_INITIALIZE_WITH) { // test initialize_with this->initialize_with( i, j + k); } // This is needed to prevent VC7.1 and VC8 to call // the explicit templated constructor in Base instead of its copy-ctor. Int_t( Int_t const& rhs ) : Base( static_cast(rhs) ) {} int value() const { return this->ptr()->val; } void set_value( int i) { this->copy_on_write(); this->ptr()->val = i; } bool operator==( const Int_t& i) const { bool equal = (value() == i.value()); if ( equal) Base::unify(i); return equal; } }; void test_handle() { { // test template constructor and initialize_with typedef Int_t< ::CGAL::Handle_policy_no_union> Int; Int i(5,6); assert( i == Int(11)); Int j(5,6,7); assert( j == Int(18)); } { typedef Int_t< ::CGAL::Handle_policy_in_place> Int; Int i(5); Int j(5); Int k(6); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( i == j); assert( ! (i == k)); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); } { typedef Int_t< ::CGAL::Handle_policy_no_union> Int; Int i(5); Int j(5); Int k(6); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( i == j); assert( ! (i == k)); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( (std::ptrdiff_t)(ID_Number(i)) == i.id() ); } { typedef Int_t< ::CGAL::Handle_policy_union> Int; Int i(5); Int j(5); Int k(6); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( i == j); assert( ! (i == k)); assert( i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); } { typedef Int_t< ::CGAL::Handle_policy_union_and_reset> Int; Int i(5); Int j(5); Int k(6); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( i == j); assert( ! (i == k)); assert( i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); } { typedef Int_t< ::CGAL::Handle_policy_union> Int; Int i(5); Int j(5); Int k(5); Int l(5); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( ! j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( ! k.test_identical_ptr( l)); // pump up the union_size counter for j, k and l Int j1(j); assert( j1.test_identical_ptr( j)); Int k1(k); Int k2(k); Int k3(k); Int l1(l); Int l2(l); Int l3(l); Int l4(l); Int l5(l); Int l6(l); Int l7(l); Int l8(l); assert( ! i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 2); assert( j.union_size() == 3); assert( k.union_size() == 5); assert( l.union_size() == 10); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( ! j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( ! k.test_identical_ptr( l)); // link i to j assert( i == j); assert( ! i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 4); assert( j.union_size() == 4); assert( k.union_size() == 5); assert( l.union_size() == 10); assert( i.test_identical_ptr( j)); assert( i.test_identical_ptr( j1)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( ! j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( ! k.test_identical_ptr( l)); // link j to k assert( j == k); assert( i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 3); assert( j.union_size() == 9); assert( k.union_size() == 9); assert( l.union_size() == 10); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( ! k.test_identical_ptr( l)); // link k to l assert( k == l); assert( i.is_forwarding()); assert( j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 3); assert( j.union_size() == 8); assert( k.union_size() == 19); assert( l.union_size() == 19); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( ! j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( k.test_identical_ptr( l)); // find j, links it to k and l assert( j.value() == 5); assert( i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 3); assert( j.union_size() == 19); assert( k.union_size() == 19); assert( l.union_size() == 19); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( j.test_identical_ptr( k)); assert( j.test_identical_ptr( l)); assert( k.test_identical_ptr( l)); // find i, links it to j, k and l assert( i.value() == 5); assert( ! i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 19); assert( j.union_size() == 19); assert( k.union_size() == 19); assert( l.union_size() == 19); assert( i.test_identical_ptr( j)); assert( i.test_identical_ptr( k)); assert( i.test_identical_ptr( l)); assert( j.test_identical_ptr( k)); assert( j.test_identical_ptr( l)); assert( k.test_identical_ptr( l)); } } // fully generic example to show, how allocator and policy can be transported // from the templated handle to the templated rep. For hard-coded choices // one could derive directly from one of the following base classes: // -- struct Int_vrep : public ::CGAL::Reference_counted_hierarchy_with_union<> // -- struct Int_vrep : public ::CGAL::Reference_counted_hierarchy<> template struct Int_vrep : public Policy::template Hierarchy_base< Alloc>::Type { int val; virtual CGAL::Reference_counted_hierarchy* clone() { return new Int_vrep( *this); } virtual int get_val() const { return val; } virtual void set_val( int i) { val = i; } Int_vrep( int i = 0) : val(i) {} }; template struct Int_vrep2 : public Int_vrep { int val2; virtual ::CGAL::Reference_counted_hierarchy* clone() { return new Int_vrep2( *this); } virtual int get_val() const { return this->val + val2; } virtual void set_val( int i) { this->val = i - val2; } Int_vrep2( int i, int j) : Int_vrep(i), val2(j) {} }; template struct Int_vrep3 : public Int_vrep2 { int val3; virtual ::CGAL::Reference_counted_hierarchy* clone() { return new Int_vrep3( *this); } virtual int get_val() const { return this->val + this->val2 + val3; } virtual void set_val( int i) { this->val = i - this->val2 - val3; } Int_vrep3( int i, int j, int k) : Int_vrep2(i,j), val3(k) {} }; template < class Unify, class Alloc = CGAL_ALLOCATOR(char) > struct Int_vt : public ::CGAL::Handle_with_policy< Int_vrep, Unify > { typedef ::CGAL::Handle_with_policy< Int_vrep, Unify > Base; Int_vt( int i = 0) : Base( new Int_vrep(i)) {} Int_vt( int i, int j) : Base( new Int_vrep2(i,j)) {} Int_vt( int i, int j, int k) : Base( new Int_vrep3(i,j,k)) {} // This is needed to prevent VC7.1 and VC8 to call // the explicit templated constructor in Base instead of its copy-ctor. Int_vt( Int_vt const& rhs ) : Base( static_cast(rhs) ) {} int value() const { return this->ptr()->get_val(); } void set_value( int i) { this->copy_on_write(); this->ptr()->set_val(i); } bool operator==( const Int_vt& i) const { bool equal = (value() == i.value()); if ( equal) Base::unify(i); return equal; } }; void test_handle_with_class_hierarchy() { { // test template constructor and initialize_with typedef Int_vt< ::CGAL::Handle_policy_no_union> Int; Int i(5,6); assert( i == Int(11)); Int j(5,6,7); assert( j == Int(18)); } { //typedef Int_vt< ::CGAL::Handle_policy_in_place> Int; // That's supposed to fail } { typedef Int_vt< ::CGAL::Handle_policy_no_union> Int; Int i(5); Int j(5); Int k(6); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( i == j); assert( ! (i == k)); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( (std::ptrdiff_t)(ID_Number(i)) == i.id() ); } { typedef Int_vt< ::CGAL::Handle_policy_union> Int; Int i(5); Int j(5); Int k(6); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( i == j); assert( ! (i == k)); assert( i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); } { typedef Int_vt< ::CGAL::Handle_policy_union_and_reset> Int; Int i(5); Int j(5); Int k(6); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); assert( i == j); assert( ! (i == k)); assert( i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! j.test_identical_ptr( k)); } { typedef Int_vt< ::CGAL::Handle_policy_union> Int; Int i(5); Int j(5); Int k(5); Int l(5); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( ! j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( ! k.test_identical_ptr( l)); // pump up the union_size counter for j, k and l Int j1(j); assert( j1.test_identical_ptr( j)); Int k1(k); Int k2(k); Int k3(k); Int l1(l); Int l2(l); Int l3(l); Int l4(l); Int l5(l); Int l6(l); Int l7(l); Int l8(l); assert( ! i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 2); assert( j.union_size() == 3); assert( k.union_size() == 5); assert( l.union_size() == 10); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( ! j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( ! k.test_identical_ptr( l)); // link i to j assert( i == j); assert( ! i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 4); assert( j.union_size() == 4); assert( k.union_size() == 5); assert( l.union_size() == 10); assert( i.test_identical_ptr( j)); assert( i.test_identical_ptr( j1)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( ! j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( ! k.test_identical_ptr( l)); // link j to k assert( j == k); assert( i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 3); assert( j.union_size() == 9); assert( k.union_size() == 9); assert( l.union_size() == 10); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( ! k.test_identical_ptr( l)); // link k to l assert( k == l); assert( i.is_forwarding()); assert( j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 3); assert( j.union_size() == 8); assert( k.union_size() == 19); assert( l.union_size() == 19); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( ! j.test_identical_ptr( k)); assert( ! j.test_identical_ptr( l)); assert( k.test_identical_ptr( l)); // find j, links it to k and l assert( j.value() == 5); assert( i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 3); assert( j.union_size() == 19); assert( k.union_size() == 19); assert( l.union_size() == 19); assert( ! i.test_identical_ptr( j)); assert( ! i.test_identical_ptr( k)); assert( ! i.test_identical_ptr( l)); assert( j.test_identical_ptr( k)); assert( j.test_identical_ptr( l)); assert( k.test_identical_ptr( l)); // find i, links it to j, k and l assert( i.value() == 5); assert( ! i.is_forwarding()); assert( ! j.is_forwarding()); assert( ! k.is_forwarding()); assert( ! l.is_forwarding()); assert( i.union_size() == 19); assert( j.union_size() == 19); assert( k.union_size() == 19); assert( l.union_size() == 19); assert( i.test_identical_ptr( j)); assert( i.test_identical_ptr( k)); assert( i.test_identical_ptr( l)); assert( j.test_identical_ptr( k)); assert( j.test_identical_ptr( l)); assert( k.test_identical_ptr( l)); } } int main() { test_handle(); test_handle_with_class_hierarchy(); return EXIT_SUCCESS; }