Fast RTPS  Version 2.4.1
Fast RTPS
ResourceLimitedVector.hpp
1 // Copyright 2019 Proyectos y Sistemas de Mantenimiento SL (eProsima).
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
20 #ifndef FASTRTPS_UTILS_COLLECTIONS_RESOURCELIMITEDVECTOR_HPP_
21 #define FASTRTPS_UTILS_COLLECTIONS_RESOURCELIMITEDVECTOR_HPP_
22 
23 #include "ResourceLimitedContainerConfig.hpp"
24 
25 #include <assert.h>
26 #include <algorithm>
27 #include <type_traits>
28 #include <vector>
29 
30 namespace eprosima {
31 namespace fastrtps {
32 
52 template <
53  typename _Ty,
54  typename _KeepOrderEnabler = std::false_type,
55  typename _LimitsConfig = ResourceLimitedContainerConfig,
56  typename _Alloc = std::allocator<_Ty>,
57  typename _Collection = std::vector<_Ty, _Alloc>>
59 {
60 public:
61 
62  using configuration_type = _LimitsConfig;
63  using collection_type = _Collection;
64  using value_type = _Ty;
65  using allocator_type = _Alloc;
66  using pointer = typename collection_type::pointer;
67  using const_pointer = typename collection_type::const_pointer;
68  using reference = typename collection_type::reference;
69  using const_reference = typename collection_type::const_reference;
70  using size_type = typename collection_type::size_type;
71  using difference_type = typename collection_type::difference_type;
72  using iterator = typename collection_type::iterator;
73  using const_iterator = typename collection_type::const_iterator;
74  using reverse_iterator = typename collection_type::reverse_iterator;
75  using const_reverse_iterator = typename collection_type::const_reverse_iterator;
76 
91  const allocator_type& alloc = allocator_type())
92  : configuration_(cfg)
93  , collection_(alloc)
94  {
95  collection_.reserve(cfg.initial);
96  }
97 
99  const ResourceLimitedVector& other)
101  , collection_(other.collection_.get_allocator())
102  {
103  collection_.reserve(other.collection_.capacity());
104  collection_.assign(other.collection_.begin(), other.collection_.end());
105  }
106 
107  virtual ~ResourceLimitedVector () = default;
108 
110  const ResourceLimitedVector& other)
111  {
112  clear();
113  for (const_reference item : other)
114  {
115  push_back(item);
116  }
117 
118  assert(size() == other.size());
119  return *this;
120  }
121 
133  const value_type& val)
134  {
135  return emplace_back(val);
136  }
137 
149  value_type&& val)
150  {
151  if (!ensure_capacity())
152  {
153  // Indicate error by returning null pointer
154  return nullptr;
155  }
156 
157  // Move the element at the end of the collection
158  collection_.push_back(std::move(val));
159 
160  // Return pointer to newly created element
161  return &collection_.back();
162  }
163 
174  template<typename ... Args>
176  Args&& ... args)
177  {
178  if (!ensure_capacity())
179  {
180  // Indicate error by returning null pointer
181  return nullptr;
182  }
183 
184  // Construct new element at the end of the collection
185  collection_.emplace_back(args ...);
186 
187  // Return pointer to newly created element
188  return &collection_.back();
189  }
190 
201  bool remove(
202  const value_type& val)
203  {
204  iterator it = std::find(collection_.begin(), collection_.end(), val);
205  if (it != collection_.end())
206  {
207  do_remove(it);
208  return true;
209  }
210  return false;
211  }
212 
228  template<class UnaryPredicate>
229  bool remove_if(
230  UnaryPredicate pred)
231  {
232  iterator it = std::find_if(collection_.begin(), collection_.end(), pred);
233  if (it != collection_.end())
234  {
235  do_remove(it);
236  return true;
237  }
238  return false;
239  }
240 
255  template <class InputIterator>
256  void assign(
257  InputIterator first,
258  InputIterator last)
259  {
260  size_type n = static_cast<size_type>(std::distance(first, last));
261  n = (std::min)(n, configuration_.maximum);
262  InputIterator value = first;
263  std::advance(value, n);
264  collection_.assign(first, value);
265  }
266 
277  void assign(
278  size_type n,
279  const value_type& val)
280  {
281  n = (std::min)(n, configuration_.maximum);
282  collection_.assign(n, val);
283  }
284 
296  void assign(
297  std::initializer_list<value_type> il)
298  {
299  size_type n = (std::min)(il.size(), configuration_.maximum);
300  collection_.assign(il.begin(), il.begin() + n);
301  }
302 
309  size_type pos)
310  {
311  return collection_.at(pos);
312  }
313 
315  size_type pos) const
316  {
317  return collection_.at(pos);
318  }
319 
321  size_type pos)
322  {
323  return collection_[pos];
324  }
325 
327  size_type pos) const
328  {
329  return collection_[pos];
330  }
331 
333  {
334  return collection_.front();
335  }
336 
338  {
339  return collection_.front();
340  }
341 
343  {
344  return collection_.back();
345  }
346 
348  {
349  return collection_.back();
350  }
351 
352  iterator begin() noexcept
353  {
354  return collection_.begin();
355  }
356 
357  const_iterator begin() const noexcept
358  {
359  return collection_.begin();
360  }
361 
362  const_iterator cbegin() const noexcept
363  {
364  return collection_.cbegin();
365  }
366 
367  iterator end() noexcept
368  {
369  return collection_.end();
370  }
371 
372  const_iterator end() const noexcept
373  {
374  return collection_.end();
375  }
376 
377  const_iterator cend() const noexcept
378  {
379  return collection_.cend();
380  }
381 
383  {
384  return collection_.rbegin();
385  }
386 
388  {
389  return collection_.rbegin();
390  }
391 
393  {
394  return collection_.crbegin();
395  }
396 
398  {
399  return collection_.rend();
400  }
401 
402  const_reverse_iterator rend() const noexcept
403  {
404  return collection_.rend();
405  }
406 
407  const_reverse_iterator crend() const noexcept
408  {
409  return collection_.crend();
410  }
411 
412  bool empty() const noexcept
413  {
414  return collection_.empty();
415  }
416 
417  size_type size() const noexcept
418  {
419  return collection_.size();
420  }
421 
422  size_type capacity() const noexcept
423  {
424  return collection_.capacity();
425  }
426 
427  size_type max_size() const noexcept
428  {
429  return (std::min)(configuration_.maximum, collection_.max_size());
430  }
431 
432  void clear()
433  {
434  collection_.clear();
435  }
436 
438  const_iterator pos)
439  {
440  return collection_.erase(pos);
441  }
442 
444  const_iterator first,
445  const_iterator last)
446  {
447  return collection_.erase(first, last);
448  }
449 
450  void pop_back()
451  {
452  collection_.pop_back();
453  }
454 
456  {
457  return collection_.data();
458  }
459 
460  const value_type* data() const
461  {
462  return collection_.data();
463  }
464 
466 
474  operator const collection_type& () const noexcept
475  {
476  return collection_;
477  }
478 
479 protected:
480 
483 
492  {
493  size_type size = collection_.size();
494  size_type cap = collection_.capacity();
495  if (size == cap)
496  {
497  // collection is full, check resource limit
498  if (cap < configuration_.maximum)
499  {
500  // increase collection capacity
501  assert(configuration_.increment > 0);
502  cap += configuration_.increment;
503  cap = (std::min)(cap, configuration_.maximum);
504  collection_.reserve(cap);
505  }
506  else
507  {
508  return false;
509  }
510  }
511 
512  return true;
513  }
514 
524  template <typename Enabler = _KeepOrderEnabler>
525  typename std::enable_if<!Enabler::value, void>::type do_remove(
526  iterator it)
527  {
528  // Copy last element into the element being removed
529  if (it != --collection_.end())
530  {
531  *it = std::move(collection_.back());
532  }
533 
534  // Then drop last element
535  collection_.pop_back();
536  }
537 
548  template <typename Enabler = _KeepOrderEnabler>
549  typename std::enable_if<Enabler::value, void>::type do_remove(
550  iterator it)
551  {
552  collection_.erase(it);
553  }
554 
555 };
556 
557 } // namespace fastrtps
558 } // namespace eprosima
559 
560 #endif /* FASTRTPS_UTILS_COLLECTIONS_RESOURCELIMITEDVECTOR_HPP_ */
Resource limited wrapper of std::vector.
Definition: ResourceLimitedVector.hpp:59
void pop_back()
Definition: ResourceLimitedVector.hpp:450
size_type size() const noexcept
Definition: ResourceLimitedVector.hpp:417
configuration_type configuration_
Definition: ResourceLimitedVector.hpp:481
const_reference front() const
Definition: ResourceLimitedVector.hpp:337
typename collection_type::iterator iterator
Definition: ResourceLimitedVector.hpp:72
pointer push_back(value_type &&val)
Add element at the end.
Definition: ResourceLimitedVector.hpp:148
typename collection_type::difference_type difference_type
Definition: ResourceLimitedVector.hpp:71
void assign(std::initializer_list< value_type > il)
Assign vector content.
Definition: ResourceLimitedVector.hpp:296
typename collection_type::reverse_iterator reverse_iterator
Definition: ResourceLimitedVector.hpp:74
void assign(size_type n, const value_type &val)
Assign vector content.
Definition: ResourceLimitedVector.hpp:277
const_iterator begin() const noexcept
Definition: ResourceLimitedVector.hpp:357
typename collection_type::const_pointer const_pointer
Definition: ResourceLimitedVector.hpp:67
iterator erase(const_iterator pos)
Definition: ResourceLimitedVector.hpp:437
ResourceLimitedVector & operator=(const ResourceLimitedVector &other)
Definition: ResourceLimitedVector.hpp:109
_LimitsConfig configuration_type
Definition: ResourceLimitedVector.hpp:62
bool empty() const noexcept
Definition: ResourceLimitedVector.hpp:412
typename collection_type::const_reverse_iterator const_reverse_iterator
Definition: ResourceLimitedVector.hpp:75
std::enable_if<!Enabler::value, void >::type do_remove(iterator it)
Remove element.
Definition: ResourceLimitedVector.hpp:525
ResourceLimitedVector(const ResourceLimitedVector &other)
Definition: ResourceLimitedVector.hpp:98
typename collection_type::pointer pointer
Definition: ResourceLimitedVector.hpp:66
const_reference at(size_type pos) const
Definition: ResourceLimitedVector.hpp:314
reference at(size_type pos)
Wrappers to other basic vector methods.
Definition: ResourceLimitedVector.hpp:308
const_iterator end() const noexcept
Definition: ResourceLimitedVector.hpp:372
const_reference back() const
Definition: ResourceLimitedVector.hpp:347
std::enable_if< Enabler::value, void >::type do_remove(iterator it)
Remove element.
Definition: ResourceLimitedVector.hpp:549
bool remove_if(UnaryPredicate pred)
Remove element.
Definition: ResourceLimitedVector.hpp:229
typename collection_type::const_iterator const_iterator
Definition: ResourceLimitedVector.hpp:73
reference front()
Definition: ResourceLimitedVector.hpp:332
value_type * data()
Definition: ResourceLimitedVector.hpp:455
_Collection collection_type
Definition: ResourceLimitedVector.hpp:63
bool ensure_capacity()
Make room for one item.
Definition: ResourceLimitedVector.hpp:491
iterator begin() noexcept
Definition: ResourceLimitedVector.hpp:352
const_iterator cend() const noexcept
Definition: ResourceLimitedVector.hpp:377
const value_type * data() const
Definition: ResourceLimitedVector.hpp:460
iterator erase(const_iterator first, const_iterator last)
Definition: ResourceLimitedVector.hpp:443
_Ty value_type
Definition: ResourceLimitedVector.hpp:64
reference operator[](size_type pos)
Definition: ResourceLimitedVector.hpp:320
_Alloc allocator_type
Definition: ResourceLimitedVector.hpp:65
pointer push_back(const value_type &val)
Add element at the end.
Definition: ResourceLimitedVector.hpp:132
const_reverse_iterator crbegin() const noexcept
Definition: ResourceLimitedVector.hpp:392
const_iterator cbegin() const noexcept
Definition: ResourceLimitedVector.hpp:362
ResourceLimitedVector(configuration_type cfg=configuration_type(), const allocator_type &alloc=allocator_type())
Construct a ResourceLimitedVector.
Definition: ResourceLimitedVector.hpp:89
size_type max_size() const noexcept
Definition: ResourceLimitedVector.hpp:427
const_reverse_iterator rend() const noexcept
Definition: ResourceLimitedVector.hpp:402
reverse_iterator rbegin() noexcept
Definition: ResourceLimitedVector.hpp:382
void clear()
Definition: ResourceLimitedVector.hpp:432
typename collection_type::size_type size_type
Definition: ResourceLimitedVector.hpp:70
typename collection_type::reference reference
Definition: ResourceLimitedVector.hpp:68
const_reverse_iterator crend() const noexcept
Definition: ResourceLimitedVector.hpp:407
reverse_iterator rend() noexcept
Definition: ResourceLimitedVector.hpp:397
void assign(InputIterator first, InputIterator last)
Assign vector content.
Definition: ResourceLimitedVector.hpp:256
collection_type collection_
Definition: ResourceLimitedVector.hpp:482
size_type capacity() const noexcept
Definition: ResourceLimitedVector.hpp:422
pointer emplace_back(Args &&... args)
Construct and insert element at the end.
Definition: ResourceLimitedVector.hpp:175
bool remove(const value_type &val)
Remove element.
Definition: ResourceLimitedVector.hpp:201
typename collection_type::const_reference const_reference
Definition: ResourceLimitedVector.hpp:69
reference back()
Definition: ResourceLimitedVector.hpp:342
iterator end() noexcept
Definition: ResourceLimitedVector.hpp:367
const_reverse_iterator rbegin() const noexcept
Definition: ResourceLimitedVector.hpp:387
eProsima namespace.
Definition: LibrarySettingsAttributes.h:23