diff --git a/STL_Extension/include/CGAL/Base_with_time_stamp.h b/STL_Extension/include/CGAL/Base_with_time_stamp.h index 0ef77b262be..7dff85ab6d1 100644 --- a/STL_Extension/include/CGAL/Base_with_time_stamp.h +++ b/STL_Extension/include/CGAL/Base_with_time_stamp.h @@ -18,7 +18,7 @@ namespace CGAL { template class Base_with_time_stamp : public Base { - std::size_t time_stamp_ = -1; + std::size_t time_stamp_ = 0; public: using Base::Base; diff --git a/STL_Extension/include/CGAL/Compact_container.h b/STL_Extension/include/CGAL/Compact_container.h index e6e41515ff4..e82a33412d9 100644 --- a/STL_Extension/include/CGAL/Compact_container.h +++ b/STL_Extension/include/CGAL/Compact_container.h @@ -382,10 +382,17 @@ public: pointer ret = free_list; free_list = clean_pointee(ret); + std::size_t ts; + if constexpr (Time_stamper::has_timestamp) { + ts = ret->time_stamp(); + } new (ret) value_type(args...); + if constexpr (Time_stamper::has_timestamp) { + ret->set_time_stamp(ts); + } + Time_stamper::set_time_stamp(ret, time_stamp); CGAL_assertion(type(ret) == USED); ++size_; - Time_stamper::set_time_stamp(ret, time_stamp); return iterator(ret, 0); } @@ -424,7 +431,14 @@ public: CGAL_precondition(type(&*x) == USED); EraseCounterStrategy::increment_erase_counter(*x); + std::size_t ts; + if constexpr (Time_stamper::has_timestamp) { + ts = x->time_stamp(); + } std::allocator_traits::destroy(alloc, &*x); + if constexpr (Time_stamper::has_timestamp) { + x->set_time_stamp(ts); + } put_on_free_list(&*x); --size_; @@ -638,6 +652,9 @@ private: // Get the type of the pointee. static Type type(const_pointer ptr) { + if constexpr (Time_stamper::has_timestamp) { + return (Type)(ptr->time_stamp() >> Time_stamper::time_stamp_shift); + } char * p = (char *) Traits::pointer(*ptr); return (Type) (reinterpret_cast(p) - reinterpret_cast(clean_pointer(p))); @@ -646,6 +663,10 @@ private: // Sets the pointer part and the type of the pointee. static void set_type(pointer ptr, void * p, Type t) { + if constexpr (Time_stamper::has_timestamp) { + const auto ts = ptr->time_stamp() & ~(Time_stamper::time_stamp_mask); + ptr->set_time_stamp(ts | (static_cast(t) << Time_stamper::time_stamp_shift)); + } // This out of range compare is always true and causes lots of // unnecessary warnings. // CGAL_precondition(0 <= t && t < 4); diff --git a/STL_Extension/include/CGAL/Time_stamper.h b/STL_Extension/include/CGAL/Time_stamper.h index a1f2d30eb36..7afe7160eee 100644 --- a/STL_Extension/include/CGAL/Time_stamper.h +++ b/STL_Extension/include/CGAL/Time_stamper.h @@ -28,17 +28,28 @@ constexpr size_t rounded_down_log2(size_t n) template struct Time_stamper { + static constexpr bool has_timestamp = true; + static constexpr int time_stamp_shift = sizeof(std::size_t) * CHAR_BIT - 2; + static constexpr std::size_t time_stamp_mask = std::size_t(0b11) << time_stamp_shift; + static constexpr std::size_t time_stamp_is_free_mask = std::size_t(0b001) << (time_stamp_shift - 1); + static void initialize_time_stamp(T* pt) { pt->set_time_stamp(std::size_t(-1)); } + static bool is_free(const T* pt) + { + return ( pt->time_stamp() & time_stamp_is_free_mask )!= 0; + } + template static void set_time_stamp(T* pt, time_stamp_t& time_stamp_) { - if(pt->time_stamp() == std::size_t(-1)) { + if(is_free(pt)) { const std::size_t new_ts = time_stamp_++; pt->set_time_stamp(new_ts); } else { + pt->set_time_stamp(pt->time_stamp() & ~time_stamp_mask); // else: the time stamp is re-used // Enforces that the time stamp is greater than the current value. @@ -95,6 +106,7 @@ struct Time_stamper template struct No_time_stamp { + static constexpr bool has_timestamp = false; public: template static void set_time_stamp(T*, time_stamp_t&) {}