PageRenderTime 25ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/STL_Extension/doc/STL_Extension/CGAL/Concurrent_compact_container.h

https://gitlab.com/Namdhari/cgal-AnatoMeCo
C Header | 333 lines | 69 code | 38 blank | 226 comment | 0 complexity | 46606873ab47cb6ae694b7170130fc58 MD5 | raw file
  1. namespace CGAL {
  2. /// \ingroup PkgStlExtension
  3. /*!
  4. \ingroup CompactContainer
  5. The traits class `Concurrent_compact_container_traits` provides
  6. the way to access the internal pointer required for `T` to be
  7. used in a `Concurrent_compact_container<T, Allocator>`. Note that this
  8. pointer needs to be accessible even when the object is not constructed,
  9. which means it has to reside in the same memory place as `T`.
  10. You can specialize this class for your own type `T`
  11. if the default template is not suitable.
  12. You can also use `Compact_container_base` as base class for your own
  13. types `T` to make them usable with the default `Concurrent_compact_container`.
  14. \cgalHeading{Parameters}
  15. `T` is any type providing the following member functions:
  16. `void * t.for_compact_container() const;`
  17. `void *& t.for_compact_container();`.
  18. */
  19. template< typename T >
  20. class Concurrent_compact_container_traits {
  21. public:
  22. /// \name Operations
  23. /// @{
  24. /*!
  25. Returns the pointer held by `t`.
  26. The template version defines this function as: `return t.for_compact_container();
  27. */
  28. static void * pointer(const T &t);
  29. /// @}
  30. /// \name Operations
  31. /// @{
  32. /*!
  33. Returns a reference to the pointer held by `t`.
  34. The template version defines this function as: `return t.for_compact_container();`
  35. */
  36. static void * & pointer(T &t);
  37. /// @}
  38. }; /* end Concurrent_compact_container_traits */
  39. /*!
  40. \ingroup CompactContainer
  41. An object of the class `Concurrent_compact_container`
  42. is a container of objects of type `T`, which allows to call
  43. `insert` and `erase` operations concurrently.
  44. Other operations are not concurrency-safe.
  45. For example, one should not parse the container while others are modifying it.
  46. It matches all the
  47. standard requirements for reversible containers, except that
  48. the complexity of its iterator increment and decrement operations
  49. is not always guaranteed to be amortized constant time.
  50. This container is not a standard <I>sequence</I> nor <I>associative</I> container,
  51. which means the elements are stored in no particular order, and it is not
  52. possible to specify a particular place in the iterator sequence where to
  53. insert new objects. However, all dereferenceable iterators are
  54. still valid after calls to `insert()` and `erase()`, except those
  55. that have been erased (it behaves similarly to `std::list`).
  56. The main feature of this container is that it is very memory efficient:
  57. its memory size is `N*sizeof(T)+o(N)`, where `N` is the maximum size
  58. that the container has had in its past history, its `capacity()`
  59. (the memory of erased elements is not deallocated until destruction of the
  60. container or a call to `clear()`). This container has been developed in
  61. order to store large graph-like data structures like the triangulation and
  62. the halfedge data structures.
  63. It supports bidirectional iterators and allows a constant time amortized
  64. `insert()` operation. You cannot specify where to insert new objects
  65. (i.e.\ you don't know where they will end up in the iterator sequence,
  66. although `insert()` returns an iterator pointing to the newly inserted
  67. object). You can erase any element with a constant time complexity.
  68. Summary of the differences with `std::list`: it is more compact in
  69. memory since it doesn't store two additional pointers for the iterator needs.
  70. It doesn't deallocate elements until the destruction or `clear()` of the
  71. container. The iterator does not have constant amortized time complexity for
  72. the increment and decrement operations in all cases, only when not too many
  73. elements have not been freed (i.e.\ when the `size()` is close to the
  74. `capacity()`). Iterating from `begin()` to `end()` takes
  75. `O(capacity())` time, not `size()`. In the case where the container
  76. has a small `size()` compared to its `capacity()`, we advise to
  77. \"defragment the memory\" by copying the container if the iterator performance
  78. is needed.
  79. The iterators themselves can be used as `T`, they provide the necessary
  80. functions to be used by `Compact_container_traits<T>`. Moreover, they
  81. also provide a default constructor value which is not singular: it is
  82. copyable, comparable, and guaranteed to be unique under comparison
  83. (like `NULL` for pointers). This makes them suitable for use in
  84. geometric graphs like handles to vertices in triangulations.
  85. In addition, in a way inspired from the Boost.Intrusive containers, it is
  86. possible to construct iterators from references to values in containers
  87. using the `iterator_to` and `s_iterator_to` functions.
  88. The objects stored in the `Concurrent_compact_container` can optionally store an
  89. "erase counter". If it exists, i.e.\ if the object is a model of the
  90. `ObjectWithEraseCounter` concept, each time an object is erased from the
  91. container, the erase counter of the object will be incremented.
  92. For example, this erase counter can be exploited using the `CC_safe_handle`
  93. helper class, so that one can know if a handle is still pointing to the same
  94. element.
  95. Note that this is meaningful only because the
  96. `CGAL::Concurrent_compact_container` doesn't
  97. deallocate elements until the destruction or clear() of the container.
  98. \cgalHeading{Parameters}
  99. The parameter `T` is required to have a copy constructor and an
  100. assignment operator. It also needs to provide access to an internal
  101. pointer via `Compact_container_traits<T>`.
  102. The equality test and the relational order require the operators
  103. `==` and `<` for `T` respectively.
  104. The parameter `Allocator` has to match the standard allocator
  105. requirements, with value type `T`. This parameter has the default
  106. value `CGAL_ALLOCATOR(T)`.
  107. */
  108. template < class T, class Allocator >
  109. class Concurrent_compact_container
  110. {
  111. public:
  112. /// \name Types
  113. /// @{
  114. typedef unspecified_type value_type;
  115. typedef unspecified_type allocator_type;
  116. typedef unspecified_type reference;
  117. typedef unspecified_type const_reference;
  118. typedef unspecified_type pointer;
  119. typedef unspecified_type const_pointer;
  120. typedef unspecified_type size_type;
  121. typedef unspecified_type difference_type;
  122. typedef unspecified_type iterator;
  123. typedef unspecified_type const_iterator;
  124. typedef unspecified_type reverse_iterator;
  125. typedef unspecified_type const_reverse_iterator;
  126. /// @}
  127. /// \name Creation
  128. /// @{
  129. /*!
  130. introduces an empty container `ccc`, eventually specifying a particular
  131. allocator `a` as well.
  132. */
  133. explicit Concurrent_compact_container(const Allocator &a = Allocator());
  134. /*!
  135. a container with copies from the range [`first,last`), eventually
  136. specifying a particular allocator.
  137. */
  138. template < class InputIterator >
  139. Concurrent_compact_container(InputIterator first, InputIterator last,
  140. const Allocator & a = Allocator());
  141. /*!
  142. copy constructor. Each item in `ccc2` is copied. The allocator
  143. is copied. The iterator order is preserved.
  144. */
  145. // The copy constructor and assignment operator preserve the iterator order
  146. Concurrent_compact_container(const Concurrent_compact_container &ccc2);
  147. /*!
  148. assignment. Each item in `ccc2` is copied. The allocator is copied.
  149. Each item in `ccc` is deleted. The iterator order is preserved.
  150. */
  151. Concurrent_compact_container & operator=(const Concurrent_compact_container &ccc2);
  152. /*!
  153. swaps the contents of `ccc` and `ccc2` in constant time
  154. complexity. No exception is thrown.
  155. */
  156. void swap(Self &ccc2);
  157. /// @}
  158. /// \name Access Member Functions
  159. /// @{
  160. /*!
  161. returns true if the element `pos` is used (i.e.\ valid).
  162. */
  163. bool is_used(const_iterator pos) const;
  164. /// returns a mutable iterator referring to the first element in `ccc`.
  165. iterator begin();
  166. /// returns a constant iterator referring to the first element in `ccc`.
  167. const_iterator begin() const;
  168. /// returns a mutable iterator which is the past-end-value of `ccc`.
  169. iterator end();
  170. /// returns a constant iterator which is the past-end-value of `ccc`.
  171. const_iterator end();
  172. /// returns a mutable reverse iterator referring to the reverse beginning in `ccc`.
  173. reverse_iterator rbegin();
  174. /// returns a constant reverse iterator referring to the reverse beginning in `ccc`.
  175. const_reverse_iterator rbegin() const;
  176. /// returns a mutable reverse iterator which is the reverse past-end-value of `ccc`.
  177. reverse_iterator rend();
  178. /// returns a constant reverse iterator which is the reverse past-end-value of `ccc`.
  179. const_reverse_iterator rend() const;
  180. /// returns an iterator which points to `value`.
  181. iterator iterator_to(reference value) const;
  182. /// returns a constant iterator which points to `value`.
  183. const_iterator iterator_to(const_reference value) const;
  184. /// returns an iterator which points to `value`.
  185. static iterator s_iterator_to(reference value);
  186. /// returns a constant iterator which points to `value`.
  187. static const_iterator s_iterator_to(const_reference value);
  188. /// returns `true` iff `ccc` is empty.
  189. bool empty() const;
  190. /// returns the number of items in `ccc`.
  191. /// Note: do not call this function while others are inserting/erasing elements
  192. size_type size() const;
  193. /// returns the maximum possible size of the container `ccc`.
  194. /// This is the allocator's max_size value
  195. size_type max_size() const;
  196. /// returns the total number of elements that `ccc` can hold without requiring reallocation.
  197. size_type capacity() const;
  198. /// returns the allocator
  199. Allocator get_allocator() const;
  200. /// @}
  201. /// \name Insertion
  202. /// @{
  203. /*!
  204. constructs an object of type `T` with the constructor that takes
  205. `t1` as argument, inserts it in `ccc`, and returns the iterator pointing
  206. to it. Overloads of this member function are defined that take additional
  207. arguments, up to 9.
  208. */
  209. template < class T1 >
  210. iterator emplace(const T1& t1);
  211. /*!
  212. inserts a copy of `t` in `ccc` and returns the iterator pointing
  213. to it.
  214. */
  215. iterator insert(const T &t);
  216. /// inserts the range [`first, last`) in `ccc`.
  217. template < class InputIterator >
  218. void insert(InputIterator first, InputIterator last);
  219. /*!
  220. erases all the elements of `ccc`, then inserts the range
  221. [`first, last`) in `ccc`.
  222. */
  223. template < class InputIterator >
  224. void assign(InputIterator first, InputIterator last);
  225. /// @}
  226. /// \name Removal
  227. /// @{
  228. /// removes the item pointed by `pos` from `ccc`.
  229. void erase(iterator x);
  230. /// removes the items from the range [`first, last`) from `ccc`.
  231. void erase(iterator first, iterator last);
  232. /*!
  233. all items in `ccc` are deleted, and the memory is deallocated.
  234. After this call, `ccc` is in the same state as if just default
  235. constructed.
  236. */
  237. void clear();
  238. /// @}
  239. /// \name Ownership testing
  240. /// The following functions are mostly helpful for efficient debugging, since
  241. /// their complexity is \f$ O(\sqrt{\mathrm{c.capacity()}})\f$.
  242. /// @{
  243. /// returns whether `pos` is in the range `[ccc.begin(), ccc.end()]` (`ccc.end()` included).
  244. bool owns(const_iterator pos);
  245. /// returns whether `pos` is in the range `[ccc.begin(), ccc`.end())` (`ccc.end()` excluded).
  246. bool owns_dereferencable(const_iterator pos);
  247. /// @}
  248. /// \name Merging
  249. /// @{
  250. /*!
  251. adds the items of `ccc2` to the end of `ccc` and `ccc2` becomes empty.
  252. The time complexity is O(`ccc`.`capacity()`-`ccc`.`size()`).
  253. \pre `ccc2` must not be the same as `ccc`, and the allocators of `ccc` and `ccc2` must be compatible: `ccc.get_allocator() == ccc2.get_allocator()`.
  254. */
  255. void merge(Concurrent_compact_container<T, Allocator> &ccc2);
  256. /// @}
  257. /// \name Comparison Operations
  258. /// @{
  259. /*!
  260. test for equality: Two containers are equal, iff they have the
  261. same size and if their corresponding elements are equal.
  262. */
  263. bool operator==(const Concurrent_compact_container<T, Allocator> &ccc2) const;
  264. /// test for inequality: returns `!(ccc == ccc2)`.
  265. bool operator!=(const Concurrent_compact_container<T, Allocator> &ccc2) const;
  266. /// compares in lexicographical order.
  267. bool operator<(const Concurrent_compact_container<T, Allocator> &ccc2) const;
  268. /// returns `ccc2 < ccc`.
  269. bool operator>(const Concurrent_compact_container<T, Allocator> &ccc2) const;
  270. /// returns `!(ccc > ccc2)`.
  271. bool operator<=(const Concurrent_compact_container<T, Allocator> &ccc2) const;
  272. /// returns `!(ccc < ccc2)`.
  273. bool operator>=(const Concurrent_compact_container<T, Allocator> &ccc2) const;
  274. /// @}
  275. }; /* end Concurrent_compact_container */
  276. } /* end namespace CGAL */