HeterogenousContinuousContainer.h
Go to the documentation of this file.
1 /*
2  * This file is part of ArmarX.
3  *
4  * ArmarX is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * ArmarX is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program. If not, see <http://www.gnu.org/licenses/>.
15  *
16  * @package RobotAPI::RobotUnit
17  * @author Raphael Grimm ( raphael dot grimm at kit dot edu )
18  * @date 2018
19  * @copyright http://www.gnu.org/licenses/gpl-2.0.txt
20  * GNU General Public License
21  */
22 
23 #pragma once
24 
25 #include <vector>
26 
30 
32 
33 #if __GNUC__ < 5 && !defined(__clang__)
34 namespace std
35 {
36  inline void*
37  align(size_t alignment, size_t bytes, void*& bufferPlace, size_t& bufferSpace) noexcept
38  {
39  const auto uiptr = reinterpret_cast<uintptr_t>(bufferPlace);
40  const auto alignedPlace = (uiptr - 1u + alignment) & -alignment;
41  const auto spaceRequired = alignedPlace - uiptr;
42  if ((bytes + spaceRequired) > bufferSpace)
43  {
44  return nullptr;
45  }
46  else
47  {
48  bufferSpace -= spaceRequired;
49  return bufferPlace = reinterpret_cast<void*>(alignedPlace);
50  }
51  }
52 } // namespace std
53 #endif
54 
55 namespace armarx::detail
56 {
57  template <class Base>
59  {
60  public:
61  bool
62  empty() const
63  {
64  return begin_ == current_;
65  }
66 
67  bool
68  owning() const
69  {
70  return storage_ != nullptr;
71  }
72 
73  std::size_t
75  {
76  return static_cast<const std::uint8_t*>(end_) -
77  static_cast<const std::uint8_t*>(current_);
78  }
79 
80  std::size_t
82  {
83  return static_cast<const std::uint8_t*>(end_) -
84  static_cast<const std::uint8_t*>(begin_);
85  }
86 
87  std::size_t
89  {
90  return static_cast<const std::uint8_t*>(current_) -
91  static_cast<const std::uint8_t*>(begin_);
92  }
93 
94  void
95  assignStorage(void* begin, void* end)
96  {
98  ARMARX_CHECK_LESS_EQUAL(begin, end);
99  storage_ = nullptr;
100  begin_ = begin;
101  current_ = begin;
102  end_ = end;
103  }
104 
105  void
106  setStorageCapacity(std::size_t sz)
107  {
109  if (!sz)
110  {
111  assignStorage(nullptr, nullptr);
112  return;
113  }
114  //replache with void* aligned_alloc( std::size_t alignment, std::size_t size ) @c++17
115  sz += 63;
116  storage_.reset(new std::uint8_t[sz]);
117  begin_ = static_cast<void*>(storage_.get());
118  current_ = begin_;
119  end_ = static_cast<void*>(storage_.get() + sz);
120  }
121 
122  protected:
123  template <class Derived>
124  Base*
125  pushBack(const Derived* d)
126  {
127  static_assert(
129  "HeterogenousContinuousContainerBase::pushBack: Derived must derive Base");
130  std::size_t space_ = getRemainingStorageCapacity();
131 
132  void* ptr = std::align(d->_alignof(), d->_sizeof(), current_, space_);
133 
134  if (!ptr)
135  {
136  return nullptr;
137  }
138  current_ = static_cast<void*>(static_cast<std::uint8_t*>(ptr) + d->_sizeof());
139  return d->_placementCopyConstruct(ptr);
140  }
141 
142  void
144  {
145  current_ = begin_;
146  }
147 
148  private:
149  std::unique_ptr<std::uint8_t[]> storage_{nullptr};
150  void* begin_{nullptr};
151  void* current_{nullptr};
152  void* end_{nullptr};
153  };
154 } // namespace armarx::detail
155 
156 namespace armarx
157 {
158  template <class Base, bool UsePropagateConst = true>
160  {
162 
163  public:
164  using ElementType =
165  typename std::conditional<UsePropagateConst, PropagateConst<Base*>, Base*>::type;
166 
169 
171  bool compressElems = false)
172  {
173  this->setStorageCapacity(compressElems ? other.getUsedStorageCapacity()
174  : other.getStorageCapacity());
175  setElementCapacity(compressElems ? other.elements().size()
176  : other.elements().capacity());
177  for (auto& e : other.elements())
178  {
179  pushBack(e);
180  }
181  }
182 
184 
187  {
188  clear();
190  setElementCapacity(other.elements().capacity());
191  for (auto& e : other.elements())
192  {
193  pushBack(e);
194  }
195  return *this;
196  }
197 
199  {
200  clear();
201  }
202 
203  std::size_t
205  {
206  return elements_.size();
207  }
208 
209  std::size_t
211  {
212  return elements_.capacity();
213  }
214 
215  std::size_t
217  {
218  return getElementCapacity() - getElementCount();
219  }
220 
221  void
222  setElementCapacity(std::size_t cnt)
223  {
225  if (elements_.capacity() > cnt)
226  {
227  //force the capacity to reduce
228  elements_ = std::vector<ElementType>{};
229  }
230  elements_.reserve(cnt);
231  }
232 
233  template <class Derived>
234  Base*
235  pushBack(const Derived* d)
236  {
237  static_assert(
239  "HeterogenousContinuousContainerBase::pushBack: Derived must derive Base");
242  {
243  return nullptr;
244  }
245  Base* const ptr = BaseContainer::pushBack(d);
246  if (ptr)
247  {
248  elements_.emplace_back(ptr);
249  }
250  return ptr;
251  }
252 
253  template <class Derived>
254  Base*
256  {
257  return pushBack(*d);
258  }
259 
260  template <class Derived>
261  Base*
262  pushBack(const Derived& d)
263  {
264  return pushBack(&d);
265  }
266 
267  std::vector<ElementType>&
269  {
270  return elements_;
271  }
272 
273  const std::vector<ElementType>&
274  elements() const
275  {
276  return elements_;
277  }
278 
279  void
281  {
282  for (auto& e : elements_)
283  {
284  e->~Base();
285  }
286  elements_.clear();
288  }
289 
290  private:
291  std::vector<ElementType> elements_;
292  };
293 
294  template <class Base, bool UsePropagateConst = true>
297  {
299 
300  public:
301  using ElementType =
302  typename std::conditional<UsePropagateConst, PropagateConst<Base*>, Base*>::type;
303 
306 
308  bool compressElems = false)
309  {
310  setStorageCapacity(compressElems ? other.getUsedStorageCapacity()
311  : other.getStorageCapacity());
312  std::vector<std::size_t> elemCaps;
313  elemCaps.reserve(other.elements().size());
314  for (const auto& d1 : other.elements())
315  {
316  elemCaps.emplace_back(compressElems ? d1.size() : d1.capacity());
317  }
318  setElementCapacity(elemCaps);
319  for (std::size_t i = 0; i < other.elements().size(); ++i)
320  {
321  for (auto& e : other.elements().at(i))
322  {
323  pushBack(i, e);
324  }
325  }
326  }
327 
329 
332  {
333  clear();
335  std::vector<std::size_t> elemCaps;
336  elemCaps.reserve(other.elements().size());
337  for (const auto& d1 : other.elements())
338  {
339  elemCaps.emplace_back(d1.capacity());
340  }
341  setElementCapacity(elemCaps);
342  for (std::size_t i = 0; i < other.elements().size(); ++i)
343  {
344  for (auto& e : other.elements().at(i))
345  {
346  pushBack(i, e);
347  }
348  }
349  return *this;
350  }
351 
353  {
354  clear();
355  }
356 
357  std::size_t
358  getElementCount(std::size_t d0) const
359  {
360  return elements_.at(d0).size();
361  }
362 
363  std::size_t
364  getElementCapacity(std::size_t d0) const
365  {
366  return elements_.at(d0).capacity();
367  }
368 
369  std::size_t
370  getRemainingElementCapacity(std::size_t d0) const
371  {
372  return getElementCapacity(d0) - getElementCount(d0);
373  }
374 
375  void
376  setElementCapacity(const std::vector<std::size_t>& cnt)
377  {
379  elements_.resize(cnt.size());
380  for (std::size_t i = 0; i < cnt.size(); ++i)
381  {
382  if (elements_.at(i).capacity() > cnt)
383  {
384  //force the capacity to reduce
385  elements_.at(i) = std::vector<ElementType>{};
386  }
387  elements_.at(i).reserve(cnt.at(i));
388  }
389  }
390 
391  template <class Derived>
392  Base*
393  pushBack(std::size_t d0, const Derived* d)
394  {
395  static_assert(
397  "HeterogenousContinuousContainerBase::pushBack: Derived must derive Base");
400  {
401  return nullptr;
402  }
403  Base* const ptr = BaseContainer::pushBack(d);
404  if (ptr)
405  {
406  elements_.at(d0).emplace_back(ptr);
407  }
408  return ptr;
409  }
410 
411  template <class Derived>
412  Base*
413  pushBack(std::size_t d0, const PropagateConst<Derived*>& d)
414  {
415  return pushBack(d0, *d);
416  }
417 
418  template <class Derived>
419  Base*
420  pushBack(std::size_t d0, const Derived& d)
421  {
422  return pushBack(d0, &d);
423  }
424 
425  std::vector<std::vector<ElementType>>&
427  {
428  return elements_;
429  }
430 
431  const std::vector<std::vector<ElementType>>&
432  elements() const
433  {
434  return elements_;
435  }
436 
437  void
439  {
440  for (auto& d1 : elements_)
441  {
442  for (auto& e : d1)
443  {
444  e->~Base();
445  }
446  d1.clear();
447  }
449  }
450 
451  private:
452  std::vector<std::vector<ElementType>> elements_;
453  };
454 } // namespace armarx
armarx::HeterogenousContinuousContainer::elements
const std::vector< ElementType > & elements() const
Definition: HeterogenousContinuousContainer.h:274
armarx::HeterogenousContinuousContainer::HeterogenousContinuousContainer
HeterogenousContinuousContainer()=default
armarx::HeterogenousContinuousContainer::getElementCount
std::size_t getElementCount() const
Definition: HeterogenousContinuousContainer.h:204
armarx::HeterogenousContinuousContainer::operator=
HeterogenousContinuousContainer & operator=(const HeterogenousContinuousContainer &other)
Definition: HeterogenousContinuousContainer.h:186
armarx::detail::HeterogenousContinuousContainerBase::getStorageCapacity
std::size_t getStorageCapacity() const
Definition: HeterogenousContinuousContainer.h:81
armarx::HeterogenousContinuousContainer::operator=
HeterogenousContinuousContainer & operator=(HeterogenousContinuousContainer &&)=default
armarx::detail::HeterogenousContinuousContainerBase::assignStorage
void assignStorage(void *begin, void *end)
Definition: HeterogenousContinuousContainer.h:95
ARMARX_CHECK_NOT_NULL
#define ARMARX_CHECK_NOT_NULL(ptr)
This macro evaluates whether ptr is not null and if it turns out to be false it will throw an Express...
Definition: ExpressionException.h:206
armarx::detail::HeterogenousContinuousContainerBase::owning
bool owning() const
Definition: HeterogenousContinuousContainer.h:68
armarx::HeterogenousContinuous2DContainer::clear
void clear()
Definition: HeterogenousContinuousContainer.h:438
armarx::detail::HeterogenousContinuousContainerBase
Definition: HeterogenousContinuousContainer.h:58
armarx::HeterogenousContinuous2DContainer::operator=
HeterogenousContinuous2DContainer & operator=(HeterogenousContinuous2DContainer &&)=default
armarx::HeterogenousContinuous2DContainer::HeterogenousContinuous2DContainer
HeterogenousContinuous2DContainer()=default
armarx::HeterogenousContinuousContainer
Definition: HeterogenousContinuousContainer.h:159
armarx::HeterogenousContinuous2DContainer::ElementType
typename std::conditional< UsePropagateConst, PropagateConst< Base * >, Base * >::type ElementType
Definition: HeterogenousContinuousContainer.h:302
armarx::HeterogenousContinuous2DContainer::~HeterogenousContinuous2DContainer
~HeterogenousContinuous2DContainer()
Definition: HeterogenousContinuousContainer.h:352
std::align
void * align(size_t alignment, size_t bytes, void *&bufferPlace, size_t &bufferSpace) noexcept
Definition: HeterogenousContinuousContainer.h:37
armarx::HeterogenousContinuous2DContainer::elements
const std::vector< std::vector< ElementType > > & elements() const
Definition: HeterogenousContinuousContainer.h:432
TemplateMetaProgramming.h
armarx::HeterogenousContinuous2DContainer::pushBack
Base * pushBack(std::size_t d0, const Derived &d)
Definition: HeterogenousContinuousContainer.h:420
armarx::HeterogenousContinuousContainer::~HeterogenousContinuousContainer
~HeterogenousContinuousContainer()
Definition: HeterogenousContinuousContainer.h:198
armarx::HeterogenousContinuous2DContainer::pushBack
Base * pushBack(std::size_t d0, const Derived *d)
Definition: HeterogenousContinuousContainer.h:393
armarx::HeterogenousContinuous2DContainer::getElementCount
std::size_t getElementCount(std::size_t d0) const
Definition: HeterogenousContinuousContainer.h:358
armarx::HeterogenousContinuous2DContainer::HeterogenousContinuous2DContainer
HeterogenousContinuous2DContainer(const HeterogenousContinuous2DContainer &other, bool compressElems=false)
Definition: HeterogenousContinuousContainer.h:307
cxxopts::value
std::shared_ptr< Value > value()
Definition: cxxopts.hpp:926
armarx::HeterogenousContinuous2DContainer::getRemainingElementCapacity
std::size_t getRemainingElementCapacity(std::size_t d0) const
Definition: HeterogenousContinuousContainer.h:370
armarx::detail::HeterogenousContinuousContainerBase::clear
void clear()
Definition: HeterogenousContinuousContainer.h:143
armarx::HeterogenousContinuousContainer::pushBack
Base * pushBack(const Derived *d)
Definition: HeterogenousContinuousContainer.h:235
armarx::HeterogenousContinuous2DContainer::operator=
HeterogenousContinuous2DContainer & operator=(const HeterogenousContinuous2DContainer &other)
Definition: HeterogenousContinuousContainer.h:331
armarx::HeterogenousContinuousContainer::elements
std::vector< ElementType > & elements()
Definition: HeterogenousContinuousContainer.h:268
armarx::HeterogenousContinuousContainer::getRemainingElementCapacity
std::size_t getRemainingElementCapacity() const
Definition: HeterogenousContinuousContainer.h:216
armarx::detail::HeterogenousContinuousContainerBase::pushBack
Base * pushBack(const Derived *d)
Definition: HeterogenousContinuousContainer.h:125
armarx::detail
Definition: ApplicationNetworkStats.cpp:34
armarx::HeterogenousContinuous2DContainer::pushBack
Base * pushBack(std::size_t d0, const PropagateConst< Derived * > &d)
Definition: HeterogenousContinuousContainer.h:413
ARMARX_CHECK_LESS_EQUAL
#define ARMARX_CHECK_LESS_EQUAL(lhs, rhs)
This macro evaluates whether lhs is less or equal (<=) rhs and if it turns out to be false it will th...
Definition: ExpressionException.h:109
armarx::detail::HeterogenousContinuousContainerBase::getUsedStorageCapacity
std::size_t getUsedStorageCapacity() const
Definition: HeterogenousContinuousContainer.h:88
armarx::HeterogenousContinuousContainer::getElementCapacity
std::size_t getElementCapacity() const
Definition: HeterogenousContinuousContainer.h:210
armarx::HeterogenousContinuousContainer::pushBack
Base * pushBack(const Derived &d)
Definition: HeterogenousContinuousContainer.h:262
ExpressionException.h
ARMARX_CHECK_EXPRESSION
#define ARMARX_CHECK_EXPRESSION(expression)
This macro evaluates the expression and if it turns out to be false it will throw an ExpressionExcept...
Definition: ExpressionException.h:73
armarx::detail::HeterogenousContinuousContainerBase::setStorageCapacity
void setStorageCapacity(std::size_t sz)
Definition: HeterogenousContinuousContainer.h:106
armarx::HeterogenousContinuousContainer::HeterogenousContinuousContainer
HeterogenousContinuousContainer(const HeterogenousContinuousContainer &other, bool compressElems=false)
Definition: HeterogenousContinuousContainer.h:170
armarx::HeterogenousContinuousContainer::pushBack
Base * pushBack(const PropagateConst< Derived * > &d)
Definition: HeterogenousContinuousContainer.h:255
armarx::HeterogenousContinuousContainer::clear
void clear()
Definition: HeterogenousContinuousContainer.h:280
std
Definition: Application.h:66
armarx::HeterogenousContinuous2DContainer::elements
std::vector< std::vector< ElementType > > & elements()
Definition: HeterogenousContinuousContainer.h:426
armarx::HeterogenousContinuous2DContainer
Definition: HeterogenousContinuousContainer.h:295
armarx::HeterogenousContinuous2DContainer::setElementCapacity
void setElementCapacity(const std::vector< std::size_t > &cnt)
Definition: HeterogenousContinuousContainer.h:376
armarx::HeterogenousContinuousContainer::ElementType
typename std::conditional< UsePropagateConst, PropagateConst< Base * >, Base * >::type ElementType
Definition: HeterogenousContinuousContainer.h:165
armarx::detail::HeterogenousContinuousContainerBase::getRemainingStorageCapacity
std::size_t getRemainingStorageCapacity() const
Definition: HeterogenousContinuousContainer.h:74
armarx::HeterogenousContinuous2DContainer::getElementCapacity
std::size_t getElementCapacity(std::size_t d0) const
Definition: HeterogenousContinuousContainer.h:364
HeterogenousContinuousContainerMacros.h
armarx::HeterogenousContinuousContainer::setElementCapacity
void setElementCapacity(std::size_t cnt)
Definition: HeterogenousContinuousContainer.h:222
armarx
This file offers overloads of toIce() and fromIce() functions for STL container types.
Definition: ArmarXTimeserver.cpp:28
armarx::detail::HeterogenousContinuousContainerBase::empty
bool empty() const
Definition: HeterogenousContinuousContainer.h:62
armarx::PropagateConst
Wrapper for a pointer to propagate const to the pointed to value.
Definition: PropagateConst.h:69
PropagateConst.h