diff --git a/STL_Extension/include/CGAL/Multiset.h b/STL_Extension/include/CGAL/Multiset.h index 65b590dec65..389880ded7c 100644 --- a/STL_Extension/include/CGAL/Multiset.h +++ b/STL_Extension/include/CGAL/Multiset.h @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace CGAL { @@ -50,7 +51,12 @@ namespace CGAL { template , - class Allocator_ = CGAL_ALLOCATOR(int)> + class Allocator_ = CGAL_ALLOCATOR(int), +#ifdef CGAL_MULTISET_USE_COMPACT_CONTAINER_AS_DEFAULT + typename UseCompactContainer = Tag_true> +#else + typename UseCompactContainer = Tag_false> +#endif class Multiset { public: @@ -59,7 +65,8 @@ public: typedef Type_ Type; typedef Compare_ Compare; typedef Allocator_ Allocator; - typedef Multiset Self; + typedef Multiset + Self; // Type definitions for STL compatibility. typedef Type value_type; @@ -224,11 +231,64 @@ protected: return (succP); } + + void* for_compact_container() const + { + return parentP; + } + + void for_compact_container (void * p) + { + reinterpret_cast(parentP) = p; + } + }; // Rebind the allocator to the Node type: - typedef std::allocator_traits Allocator_traits; - typedef typename Allocator_traits::template rebind_alloc Node_allocator; + class Default_node_allocator + { + typedef std::allocator_traits Allocator_traits; + typedef typename Allocator_traits::template rebind_alloc Base; + Base base; + + public: + + Node* allocate (const Node& n) + { + Node* new_node = base.allocate(1); + std::allocator_traits::construct(base, new_node, n); + return new_node; + } + + void deallocate (Node* n) + { + std::allocator_traits::destroy(base, n); + base.deallocate (n, 1); + } + }; + + class CC_node_allocator + { + typedef Compact_container Base; + Base base; + + public: + + Node* allocate (const Node& n) + { + Node* new_node = &*base.emplace(n); + return new_node; + } + + void deallocate (Node* n) + { + base.erase (base.iterator_to(*n)); + } + }; + + typedef typename std::conditional::type Node_allocator; public: @@ -242,7 +302,7 @@ public: class iterator { // Give the red-black tree class template access to the iterator's members. - friend class Multiset; + friend class Multiset; friend class const_iterator; public: @@ -353,7 +413,7 @@ public: class const_iterator { // Give the red-black tree class template access to the iterator's members. - friend class Multiset; + friend class Multiset; public: @@ -1429,20 +1489,7 @@ protected: * \return A pointer to the newly created node. */ Node* _allocate_node (const Type& object, - typename Node::Node_color color) -#ifdef CGAL_CFG_OUTOFLINE_MEMBER_DEFINITION_BUG - { - CGAL_multiset_assertion (color != Node::DUMMY_BEGIN && - color != Node::DUMMY_END); - - Node* new_node = node_alloc.allocate(1); - std::allocator_traits::construct(node_alloc, new_node, beginNode); - new_node->init(object, color); - return (new_node); - } -#else - ; -#endif + typename Node::Node_color color); /*! * De-allocate a tree node. @@ -1455,8 +1502,8 @@ protected: //--------------------------------------------------------- // Default constructor. // -template -Multiset::Multiset () : +template +Multiset::Multiset () : rootP (nullptr), iSize (0), iBlackHeight (0), @@ -1470,8 +1517,8 @@ Multiset::Multiset () : //--------------------------------------------------------- // Constructor with a pointer to comparison object. // -template -Multiset::Multiset (const Compare& comp) : +template +Multiset::Multiset (const Compare& comp) : rootP (nullptr), iSize (0), iBlackHeight (0), @@ -1485,8 +1532,8 @@ Multiset::Multiset (const Compare& comp) : //--------------------------------------------------------- // Copy constructor. // -template -Multiset::Multiset (const Self& tree) : +template +Multiset::Multiset (const Self& tree) : rootP (nullptr), iSize (tree.iSize), iBlackHeight (tree.iBlackHeight), @@ -1517,9 +1564,12 @@ Multiset::Multiset (const Self& tree) : //--------------------------------------------------------- // Destructor. // -template -Multiset::~Multiset () +template +Multiset::~Multiset () { + if (UseCompactContainer::value) + return; + // Delete the entire tree recursively. if (rootP != nullptr) _destroy (rootP); @@ -1532,9 +1582,9 @@ Multiset::~Multiset () //--------------------------------------------------------- // Assignment operator. // -template -Multiset& -Multiset::operator= (const Self& tree) +template +Multiset& +Multiset::operator= (const Self& tree) { // Avoid self-assignment. if (this == &tree) @@ -1570,8 +1620,8 @@ Multiset::operator= (const Self& tree) //--------------------------------------------------------- // Swap two trees (replace their contents). // -template -void Multiset::swap (Self& tree) +template +void Multiset::swap (Self& tree) { // Avoid self-swapping. if (this == &tree) @@ -1613,8 +1663,8 @@ void Multiset::swap (Self& tree) //--------------------------------------------------------- // Test two trees for equality. // -template -bool Multiset::operator== (const Self& tree) const +template +bool Multiset::operator== (const Self& tree) const { // The sizes of the two trees must be the same. if (size() != tree.size()) @@ -1640,8 +1690,8 @@ bool Multiset::operator== (const Self& tree) const //--------------------------------------------------------- // Check if our tree is lexicographically smaller that a given tree. // -template -bool Multiset::operator< (const Self& tree) const +template +bool Multiset::operator< (const Self& tree) const { // Go over all elements in both tree and compare them pairwise. const_iterator it1 = this->begin(); @@ -1680,9 +1730,9 @@ bool Multiset::operator< (const Self& tree) const //--------------------------------------------------------- // Get an iterator for the minimum object in the tree (non-const version). // -template -inline typename Multiset::iterator -Multiset::begin () +template +inline typename Multiset::iterator +Multiset::begin () { if (beginNode.parentP != nullptr) return (iterator (beginNode.parentP)); @@ -1693,9 +1743,9 @@ Multiset::begin () //--------------------------------------------------------- // Get a past-the-end iterator for the tree objects (non-const version). // -template -inline typename Multiset::iterator -Multiset::end () +template +inline typename Multiset::iterator +Multiset::end () { return (iterator (&endNode)); } @@ -1703,9 +1753,9 @@ Multiset::end () //--------------------------------------------------------- // Get an iterator for the minimum object in the tree (const version). // -template -inline typename Multiset::const_iterator -Multiset::begin () const +template +inline typename Multiset::const_iterator +Multiset::begin () const { if (beginNode.parentP != nullptr) return (const_iterator (beginNode.parentP)); @@ -1716,9 +1766,9 @@ Multiset::begin () const //--------------------------------------------------------- // Get a past-the-end iterator for the tree objects (const version). // -template -inline typename Multiset::const_iterator -Multiset::end () const +template +inline typename Multiset::const_iterator +Multiset::end () const { return (const_iterator (&endNode)); } @@ -1727,9 +1777,9 @@ Multiset::end () const // Get a reverse iterator for the maxnimum object in the tree // (non-const version). // -template -inline typename Multiset::reverse_iterator -Multiset::rbegin () +template +inline typename Multiset::reverse_iterator +Multiset::rbegin () { return (reverse_iterator (end())); } @@ -1738,9 +1788,9 @@ Multiset::rbegin () // Get a pre-the-begin reverse iterator for the tree objects // (non-const version). // -template -inline typename Multiset::reverse_iterator -Multiset::rend () +template +inline typename Multiset::reverse_iterator +Multiset::rend () { return (reverse_iterator (begin())); } @@ -1748,9 +1798,9 @@ Multiset::rend () //--------------------------------------------------------- // Get a reverse iterator for the maximum object in the tree (const version). // -template -inline typename Multiset::const_reverse_iterator -Multiset::rbegin () const +template +inline typename Multiset::const_reverse_iterator +Multiset::rbegin () const { return (const_reverse_iterator (end())); } @@ -1758,9 +1808,9 @@ Multiset::rbegin () const //--------------------------------------------------------- // Get a pre-the-begin reverse iterator for the tree objects (const version). // -template -inline typename Multiset::const_reverse_iterator -Multiset::rend () const +template +inline typename Multiset::const_reverse_iterator +Multiset::rend () const { return (const_reverse_iterator (begin())); } @@ -1768,8 +1818,8 @@ Multiset::rend () const //--------------------------------------------------------- // Get the size of the tree. // -template -size_t Multiset::size () const +template +size_t Multiset::size () const { if (rootP == nullptr) // The tree is empty: @@ -1798,9 +1848,9 @@ size_t Multiset::size () const //--------------------------------------------------------- // Insert a new object to the tree. // -template -typename Multiset::iterator -Multiset::insert (const Type& object) +template +typename Multiset::iterator +Multiset::insert (const Type& object) { if (rootP == nullptr) { @@ -1897,9 +1947,9 @@ Multiset::insert (const Type& object) //--------------------------------------------------------- // Insert an object to the tree, with a given hint to its position. // -template -typename Multiset::iterator -Multiset::insert (iterator position, +template +typename Multiset::iterator +Multiset::insert (iterator position, const Type& object) { Node *nodeP = position.nodeP; @@ -1973,9 +2023,9 @@ Multiset::insert (iterator position, //--------------------------------------------------------- // Insert a new object to the tree as the a successor of a given node. // -template -typename Multiset::iterator -Multiset::insert_after (iterator position, +template +typename Multiset::iterator +Multiset::insert_after (iterator position, const Type& object) { Node *nodeP = position.nodeP; @@ -2071,9 +2121,9 @@ Multiset::insert_after (iterator position, //--------------------------------------------------------- // Insert a new object to the tree as the a predecessor of a given node. // -template -typename Multiset::iterator -Multiset::insert_before (iterator position, +template +typename Multiset::iterator +Multiset::insert_before (iterator position, const Type& object) { Node *nodeP = position.nodeP; @@ -2169,8 +2219,8 @@ Multiset::insert_before (iterator position, //--------------------------------------------------------- // Remove an object from the tree. // -template -size_t Multiset::erase (const Type& object) +template +size_t Multiset::erase (const Type& object) { // Find the first node containing an object not less than the object to // be erased and from there look for objects equivalent to the given object. @@ -2201,8 +2251,8 @@ size_t Multiset::erase (const Type& object) //--------------------------------------------------------- // Remove the object pointed by the given iterator. // -template -void Multiset::erase (iterator position) +template +void Multiset::erase (iterator position) { Node *nodeP = position.nodeP; @@ -2215,8 +2265,8 @@ void Multiset::erase (iterator position) //--------------------------------------------------------- // Remove all objects from the tree. // -template -void Multiset::clear () +template +void Multiset::clear () { // Delete all the tree nodes recursively. if (rootP != nullptr) @@ -2236,8 +2286,8 @@ void Multiset::clear () //--------------------------------------------------------- // Replace the object pointed by a given iterator with another object. // -template -void Multiset::replace (iterator position, +template +void Multiset::replace (iterator position, const Type& object) { Node *nodeP = position.nodeP; @@ -2264,8 +2314,8 @@ void Multiset::replace (iterator position, //--------------------------------------------------------- // Swap the location two objects in the tree, given by their positions. // -template -void Multiset::swap (iterator pos1, +template +void Multiset::swap (iterator pos1, iterator pos2) { Node *node1_P = pos1.nodeP; @@ -2310,8 +2360,8 @@ void Multiset::swap (iterator pos1, //--------------------------------------------------------- // Check if the tree is a valid one. // -template -bool Multiset::is_valid () const +template +bool Multiset::is_valid () const { if (rootP == nullptr) { @@ -2362,8 +2412,8 @@ bool Multiset::is_valid () const //--------------------------------------------------------- // Get the height of the tree. // -template -size_t Multiset::height () const +template +size_t Multiset::height () const { if (rootP == nullptr) // Empty tree. @@ -2376,8 +2426,8 @@ size_t Multiset::height () const //--------------------------------------------------------- // Catenate the tree with another given tree. // -template -void Multiset::catenate (Self& tree) +template +void Multiset::catenate (Self& tree) { // Get the maximal node in our tree and the minimal node in the other tree. Node *max1_P = endNode.parentP; @@ -2614,8 +2664,8 @@ void Multiset::catenate (Self& tree) // in the range [begin, position) and all objects in the range // [position, end) form a new output tree. // -template -void Multiset::split (iterator position, +template +void Multiset::split (iterator position, Self& tree) { CGAL_multiset_precondition (tree.empty()); @@ -3032,8 +3082,8 @@ void Multiset::split (iterator position, // Move the contents of one tree to another without actually duplicating // the nodes. This operation also clears the copied tree. // -template -void Multiset::_shallow_assign (Self& tree) +template +void Multiset::_shallow_assign (Self& tree) { // Copy the assigned tree properties. rootP = tree.rootP; @@ -3060,8 +3110,8 @@ void Multiset::_shallow_assign (Self& tree) //--------------------------------------------------------- // Clear the properties of the tree, without actually deallocating its nodes. // -template -void Multiset::_shallow_clear () +template +void Multiset::_shallow_clear () { rootP = nullptr; iSize = 0; @@ -3075,8 +3125,8 @@ void Multiset::_shallow_clear () //--------------------------------------------------------- // Remove the given tree node. // -template -void Multiset::_remove_at (Node* nodeP) +template +void Multiset::_remove_at (Node* nodeP) { CGAL_multiset_precondition (_is_valid (nodeP)); @@ -3191,8 +3241,8 @@ void Multiset::_remove_at (Node* nodeP) //--------------------------------------------------------- // Swap the location two nodes in the tree. // -template -void Multiset::_swap (Node* node1_P, +template +void Multiset::_swap (Node* node1_P, Node* node2_P) { CGAL_multiset_assertion (_is_valid (node1_P)); @@ -3332,8 +3382,8 @@ void Multiset::_swap (Node* node1_P, //--------------------------------------------------------- // Swap the location two sibling nodes in the tree. // -template -void Multiset::_swap_siblings (Node* node1_P, +template +void Multiset::_swap_siblings (Node* node1_P, Node* node2_P) { CGAL_multiset_assertion (_is_valid (node1_P)); @@ -3408,8 +3458,8 @@ void Multiset::_swap_siblings (Node* node1_P, //--------------------------------------------------------- // Calculate the height of the subtree spanned by a given node. // -template -size_t Multiset::_sub_height +template +size_t Multiset::_sub_height (const Node* nodeP) const { CGAL_multiset_assertion (_is_valid (nodeP)); @@ -3432,8 +3482,8 @@ size_t Multiset::_sub_height //--------------------------------------------------------- // Calculate the height of the subtree spanned by a given node. // -template -bool Multiset::_sub_is_valid +template +bool Multiset::_sub_is_valid (const Node* nodeP, size_t& sub_size, size_t& sub_bh) const @@ -3496,9 +3546,9 @@ bool Multiset::_sub_is_valid //--------------------------------------------------------- // Get the leftmost node in the sub-tree spanned by the given node. // -template -typename Multiset::Node* -Multiset::_sub_minimum (Node* nodeP) const +template +typename Multiset::Node* +Multiset::_sub_minimum (Node* nodeP) const { CGAL_multiset_assertion (_is_valid (nodeP)); @@ -3512,9 +3562,9 @@ Multiset::_sub_minimum (Node* nodeP) const //--------------------------------------------------------- // Get the rightmost node in the sub-tree spanned by the given node. // -template -typename Multiset::Node* -Multiset::_sub_maximum (Node* nodeP) const +template +typename Multiset::Node* +Multiset::_sub_maximum (Node* nodeP) const { CGAL_multiset_assertion (_is_valid (nodeP)); @@ -3535,8 +3585,8 @@ Multiset::_sub_maximum (Node* nodeP) const // / \ <-------------- / \ . // T1 T2 T2 T3 // -template -void Multiset::_rotate_left (Node* xNodeP) +template +void Multiset::_rotate_left (Node* xNodeP) { // Get the right child of the node. Node *yNodeP = xNodeP->rightP; @@ -3581,8 +3631,8 @@ void Multiset::_rotate_left (Node* xNodeP) //--------------------------------------------------------- // Right-rotate the sub-tree spanned by the given node. // -template -void Multiset::_rotate_right (Node* yNodeP) +template +void Multiset::_rotate_right (Node* yNodeP) { // Get the left child of the node. Node *xNodeP = yNodeP->leftP; @@ -3627,9 +3677,9 @@ void Multiset::_rotate_right (Node* yNodeP) //--------------------------------------------------------- // Duplicate the entire sub-tree rooted at the given node. // -template -typename Multiset::Node* -Multiset::_duplicate (const Node* nodeP) +template +typename Multiset::Node* +Multiset::_duplicate (const Node* nodeP) { CGAL_multiset_assertion (_is_valid (nodeP)); @@ -3656,8 +3706,8 @@ Multiset::_duplicate (const Node* nodeP) //--------------------------------------------------------- // Destroy the entire sub-tree rooted at the given node. // -template -void Multiset::_destroy (Node* nodeP) +template +void Multiset::_destroy (Node* nodeP) { CGAL_multiset_assertion (_is_valid (nodeP)); @@ -3679,8 +3729,8 @@ void Multiset::_destroy (Node* nodeP) //--------------------------------------------------------- // Fix-up the tree so it maintains the red-black properties after insertion. // -template -void Multiset::_insert_fixup (Node* nodeP) +template +void Multiset::_insert_fixup (Node* nodeP) { CGAL_multiset_precondition (_is_red (nodeP)); @@ -3791,8 +3841,8 @@ void Multiset::_insert_fixup (Node* nodeP) //--------------------------------------------------------- // Fix-up the tree so it maintains the red-black properties after removal. // -template -void Multiset::_remove_fixup (Node* nodeP, +template +void Multiset::_remove_fixup (Node* nodeP, Node* parentP) { Node *currP = nodeP; @@ -3953,33 +4003,27 @@ void Multiset::_remove_fixup (Node* nodeP, //--------------------------------------------------------- // Allocate and initialize new tree node. // -#ifndef CGAL_CFG_OUTOFLINE_MEMBER_DEFINITION_BUG -template -typename Multiset::Node* -Multiset::_allocate_node +template +typename Multiset::Node* +Multiset::_allocate_node (const Type& object, typename Node::Node_color color) { CGAL_multiset_assertion (color != Node::DUMMY_BEGIN && color != Node::DUMMY_END); - Node* new_node = node_alloc.allocate(1); - std::allocator_traits::construct(node_alloc, new_node, beginNode); + Node* new_node = node_alloc.allocate(beginNode); new_node->init(object, color); return (new_node); } -#endif //--------------------------------------------------------- // De-allocate a tree node. // -template -void Multiset::_deallocate_node (Node* nodeP) +template +void Multiset::_deallocate_node (Node* nodeP) { - std::allocator_traits::destroy(node_alloc, nodeP); - node_alloc.deallocate (nodeP, 1); - - return; + node_alloc.deallocate (nodeP); } } //namespace CGAL diff --git a/STL_Extension/test/STL_Extension/CMakeLists.txt b/STL_Extension/test/STL_Extension/CMakeLists.txt index 4a427003e02..accda8c020f 100644 --- a/STL_Extension/test/STL_Extension/CMakeLists.txt +++ b/STL_Extension/test/STL_Extension/CMakeLists.txt @@ -34,6 +34,11 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "test_lexcompare_outputrange.cpp" ) create_single_source_cgal_program( "test_Modifiable_priority_queue.cpp" ) create_single_source_cgal_program( "test_multiset.cpp" ) + + add_executable( test_multiset_cc "test_multiset.cpp" ) + target_link_libraries( test_multiset_cc PUBLIC CGAL::CGAL ) + target_compile_options( test_multiset_cc PUBLIC -DCGAL_MULTISET_USE_COMPACT_CONTAINER_AS_DEFAULT ) + create_single_source_cgal_program( "test_N_tuple.cpp" ) create_single_source_cgal_program( "test_namespaces.cpp" ) create_single_source_cgal_program( "test_Nested_iterator.cpp" ) diff --git a/Surface_sweep_2/include/CGAL/No_intersection_surface_sweep_2.h b/Surface_sweep_2/include/CGAL/No_intersection_surface_sweep_2.h index 95d3099e348..e959a08bc93 100644 --- a/Surface_sweep_2/include/CGAL/No_intersection_surface_sweep_2.h +++ b/Surface_sweep_2/include/CGAL/No_intersection_surface_sweep_2.h @@ -143,7 +143,8 @@ protected: public: typedef CGAL::Surface_sweep_2::Event_comparer Event_comparer; - typedef Multiset Event_queue; + typedef Multiset + Event_queue; typedef typename Event_queue::iterator Event_queue_iterator; typedef typename Event::Subcurve_iterator @@ -159,19 +160,11 @@ public: typedef typename Status_line::iterator Status_line_iterator; typedef std::allocator_traits Allocator_traits; - typedef typename Allocator_traits::template rebind_alloc Event_alloc; typedef typename Allocator_traits::template rebind_alloc Subcurve_alloc; protected: - /*! \struct - * An auxiliary functor for comparing event pointers. - */ - struct CompEventPtr { - Comparison_result operator()(Event* e1, Event* e2) const - { return (e1 < e2) ? SMALLER : ((e1 > e2) ? LARGER : EQUAL); } - }; - typedef Multiset Allocated_events_set; + typedef Compact_container Allocated_events_set; typedef typename Allocated_events_set::iterator Allocated_events_iterator; // Data members: @@ -204,7 +197,6 @@ protected: // may happen only with events that are // associated with isolated query points. - Event_alloc m_eventAlloc; // An allocator for the events objects. Subcurve_alloc m_subCurveAlloc; // An allocator for the subcurve objects. Event m_masterEvent; // A master Event (created once by the diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/No_intersection_surface_sweep_2_impl.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/No_intersection_surface_sweep_2_impl.h index 498984d57b5..8a1d1f04fce 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/No_intersection_surface_sweep_2_impl.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/No_intersection_surface_sweep_2_impl.h @@ -78,15 +78,6 @@ No_intersection_surface_sweep_2::~No_intersection_surface_sweep_2() // Free the event queue. delete m_queue; - - // Free all the event that have not been de-allocated so far. - Event* p_event; - Allocated_events_iterator iter = m_allocated_events.begin(); - for (; iter != m_allocated_events.end(); ++iter) { - p_event = *iter; - std::allocator_traits::destroy(m_eventAlloc, p_event); - m_eventAlloc.deallocate(p_event,1); - } } //----------------------------------------------------------------------------- @@ -125,11 +116,7 @@ template void No_intersection_surface_sweep_2::deallocate_event(Event* event) { // Remove the event from the set of allocated events. - m_allocated_events.erase(event); - - // Perfrom the actual deallocation. - std::allocator_traits::destroy(m_eventAlloc, event); - m_eventAlloc.deallocate(event, 1); + m_allocated_events.erase(m_allocated_events.iterator_to(*event)); } //----------------------------------------------------------------------------- @@ -629,12 +616,8 @@ No_intersection_surface_sweep_2::_allocate_event(const Point_2& pt, Arr_parameter_space ps_y) { // Allocate the event. - Event* e = m_eventAlloc.allocate(1); - std::allocator_traits::construct(m_eventAlloc, e, m_masterEvent); + Event* e = &*m_allocated_events.emplace(); e->init(pt, type, ps_x, ps_y); - - // Insert it to the set of allocated events. - m_allocated_events.insert(e); return e; } @@ -649,11 +632,8 @@ _allocate_event_at_open_boundary(Attribute type, Arr_parameter_space ps_x, Arr_parameter_space ps_y) { - Event* e = m_eventAlloc.allocate(1); - std::allocator_traits::construct(m_eventAlloc, e, m_masterEvent); + Event* e = &*m_allocated_events.emplace(); e->init_at_open_boundary(type, ps_x, ps_y); - - m_allocated_events.insert(e); return e; } diff --git a/Surface_sweep_2/include/CGAL/Surface_sweep_2/No_overlap_event_base.h b/Surface_sweep_2/include/CGAL/Surface_sweep_2/No_overlap_event_base.h index ba0cc57489c..aef0ceeda03 100644 --- a/Surface_sweep_2/include/CGAL/Surface_sweep_2/No_overlap_event_base.h +++ b/Surface_sweep_2/include/CGAL/Surface_sweep_2/No_overlap_event_base.h @@ -27,6 +27,60 @@ namespace CGAL { namespace Surface_sweep_2 { +// This class is used to test if `void* T::for_compact_container()` +// exists, to avoid adding a void* pointer to the Event_base structure +// if Point_2 can already be used as a handle for this +template +struct has_for_compact_container +{ +private: + + template static + auto test(void*) -> decltype(std::declval().for_compact_container() == nullptr, Tag_true()); + + template static Tag_false test(...); + +public: + + static constexpr bool value = std::is_same(nullptr)),Tag_true>::value; +}; + +template +class Event_base_for_compact_container { }; + +template +class Event_base_for_compact_container +{ + void* p = nullptr; +public: + + void* operator()(const Point_2&) const + { + return p; + } + void operator() (Point_2&, void* ptr) + { + p = ptr; + } +}; + +template +class Event_base_for_compact_container +{ + +public: + + void* operator()(const Point_2& p) const + { + return p.for_compact_container(); + } + void operator() (Point_2& p, void* ptr) + { + p.for_compact_container(ptr); + } +}; + + /*! \class No_overlap_event_base * * A class associated with an event in a surface-sweep algorithm. @@ -71,6 +125,9 @@ public: typedef typename Subcurve_container::reverse_iterator Subcurve_reverse_iterator; + typedef Event_base_for_compact_container + ::value> For_compact_container; + /*! \enum The event type (with other information bits). */ enum Attribute { @@ -102,6 +159,10 @@ protected: char m_closed; // Is the event closed (associated with // a valid point. + // A handle for the compact container (either using the functions of + // `m_point` if available, or an additional pointer) + For_compact_container m_for_compact_container; + public: /*! Default constructor. */ No_overlap_event_base() : @@ -111,6 +172,16 @@ public: m_closed(1) {} + /*! Squat the content of Point_2 for the pointer of Compact Container */ + void* for_compact_container() const + { + return m_for_compact_container(m_point); + } + void for_compact_container (void* p) + { + m_for_compact_container(m_point, p); + } + /*! Initialize an event that is associated with a valid point. */ void init(const Point_2& point, Attribute type, Arr_parameter_space ps_x, Arr_parameter_space ps_y) diff --git a/Surface_sweep_2/package_info/Surface_sweep_2/dependencies b/Surface_sweep_2/package_info/Surface_sweep_2/dependencies index 4fe31e411a2..09546686abf 100644 --- a/Surface_sweep_2/package_info/Surface_sweep_2/dependencies +++ b/Surface_sweep_2/package_info/Surface_sweep_2/dependencies @@ -2,6 +2,7 @@ Algebraic_foundations Arithmetic_kernel Arrangement_on_surface_2 Cartesian_kernel +Circulator Distance_2 Distance_3 Filtered_kernel