Zserio C++ runtime library  1.0.0
Built for Zserio 2.13.0
AnyHolder.h
Go to the documentation of this file.
1 #ifndef ZSERIO_ANY_HOLDER_H_INC
2 #define ZSERIO_ANY_HOLDER_H_INC
3 
4 #include <cstddef>
5 #include <type_traits>
6 
9 #include "zserio/NoInit.h"
10 #include "zserio/OptionalHolder.h"
11 #include "zserio/Types.h"
12 #include "zserio/Traits.h"
13 #include "zserio/RebindAlloc.h"
14 
15 namespace zserio
16 {
17 
18 namespace detail
19 {
20  class TypeIdHolder
21  {
22  public:
23  using type_id = const int*;
24 
25  template <typename T>
26  static type_id get()
27  {
28  static int currentTypeId;
29 
30  return &currentTypeId;
31  }
32  };
33 
34  // Interface for object holders
35  template <typename ALLOC>
36  class IHolder
37  {
38  public:
39  virtual ~IHolder() = default;
40  virtual IHolder* clone(const ALLOC& allocator) const = 0;
41  virtual IHolder* clone(NoInitT, const ALLOC& allocator) const = 0;
42  virtual IHolder* clone(void* storage) const = 0;
43  virtual IHolder* clone(NoInitT, void* storage) const = 0;
44  virtual IHolder* move(const ALLOC& allocator) = 0;
45  virtual IHolder* move(NoInitT, const ALLOC& allocator) = 0;
46  virtual IHolder* move(void* storage) = 0;
47  virtual IHolder* move(NoInitT, void* storage) = 0;
48  virtual void destroy(const ALLOC& allocator) = 0;
49  virtual bool isType(detail::TypeIdHolder::type_id typeId) const = 0;
50  };
51 
52  // Base of object holders, holds a value in the inplace_optional_holder
53  template <typename T, typename ALLOC>
54  class HolderBase : public IHolder<ALLOC>
55  {
56  public:
57  template <typename U>
58  void set(U&& value)
59  {
60  m_typedHolder = std::forward<U>(value);
61  }
62 
63  template <typename U,
64  typename std::enable_if<std::is_constructible<U, NoInitT, U>::value, int>::type = 0>
65  void set(NoInitT, U&& value)
66  {
67  // inplace_optional_holder constructor to prevent it's implicit constructor
68  m_typedHolder.assign(NoInit, inplace_optional_holder<T>(NoInit, std::forward<U>(value)));
69  }
70 
71  template <typename U,
72  typename std::enable_if<!std::is_constructible<U, NoInitT, U>::value, int>::type = 0>
73  void set(NoInitT, U&& value)
74  {
75  m_typedHolder = std::forward<U>(value);
76  }
77 
78  void setHolder(const inplace_optional_holder<T>& value)
79  {
80  m_typedHolder = value;
81  }
82 
83  void setHolder(inplace_optional_holder<T>&& value)
84  {
85  m_typedHolder = std::move(value);
86  }
87 
88  template <typename U,
89  typename std::enable_if<std::is_constructible<U, NoInitT, U>::value, int>::type = 0>
90  void setHolder(NoInitT, const inplace_optional_holder<U>& value)
91  {
92  m_typedHolder.assign(NoInit, value);
93  }
94 
95  template <typename U,
96  typename std::enable_if<std::is_constructible<U, NoInitT, U>::value, int>::type = 0>
97  void setHolder(NoInitT, inplace_optional_holder<U>&& value)
98  {
99  m_typedHolder.assign(NoInit, std::move(value));
100  }
101 
102  template <typename U,
103  typename std::enable_if<!std::is_constructible<U, NoInitT, U>::value, int>::type = 0>
104  void setHolder(NoInitT, const inplace_optional_holder<U>& value)
105  {
106  m_typedHolder = value;
107  }
108 
109  template <typename U,
110  typename std::enable_if<!std::is_constructible<U, NoInitT, U>::value, int>::type = 0>
111  void setHolder(NoInitT, inplace_optional_holder<U>&& value)
112  {
113  m_typedHolder = std::move(value);
114  }
115 
116  T& get()
117  {
118  return m_typedHolder.value();
119  }
120 
121  const T& get() const
122  {
123  return m_typedHolder.value();
124  }
125 
126  bool isType(detail::TypeIdHolder::type_id typeId) const override
127  {
128  return detail::TypeIdHolder::get<T>() == typeId;
129  }
130 
131  protected:
132  inplace_optional_holder<T>& getHolder()
133  {
134  return m_typedHolder;
135  }
136 
137  const inplace_optional_holder<T>& getHolder() const
138  {
139  return m_typedHolder;
140  }
141 
142  private:
143  inplace_optional_holder<T> m_typedHolder;
144  };
145 
146  // Holder allocated on heap
147  template <typename T, typename ALLOC>
148  class HeapHolder : public HolderBase<T, ALLOC>
149  {
150  private:
151  struct ConstructTag {};
152 
153  public:
154  using this_type = HeapHolder<T, ALLOC>;
155 
156  explicit HeapHolder(ConstructTag) noexcept {}
157 
158  static this_type* create(const ALLOC& allocator)
159  {
160  using AllocType = RebindAlloc<ALLOC, this_type>;
161  using AllocTraits = std::allocator_traits<AllocType>;
162 
163  AllocType typedAlloc = allocator;
164  typename AllocTraits::pointer ptr = AllocTraits::allocate(typedAlloc, 1);
165  // this never throws because HeapHolder constructor never throws
166  AllocTraits::construct(typedAlloc, std::addressof(*ptr), ConstructTag{});
167  return ptr;
168  }
169 
170  IHolder<ALLOC>* clone(const ALLOC& allocator) const override
171  {
172  this_type* holder = create(allocator);
173  holder->setHolder(this->getHolder());
174  return holder;
175  }
176 
177  IHolder<ALLOC>* clone(NoInitT, const ALLOC& allocator) const override
178  {
179  this_type* holder = create(allocator);
180  holder->setHolder(NoInit, this->getHolder());
181  return holder;
182  }
183 
184  IHolder<ALLOC>* clone(void*) const override
185  {
186  throw CppRuntimeException("AnyHolder: Unexpected clone call.");
187  }
188 
189  IHolder<ALLOC>* clone(NoInitT, void*) const override
190  {
191  throw CppRuntimeException("AnyHolder: Unexpected clone call.");
192  }
193 
194  IHolder<ALLOC>* move(const ALLOC& allocator) override
195  {
196  this_type* holder = create(allocator);
197  holder->setHolder(std::move(this->getHolder()));
198  return holder;
199  }
200 
201  IHolder<ALLOC>* move(NoInitT, const ALLOC& allocator) override
202  {
203  this_type* holder = create(allocator);
204  holder->setHolder(NoInit, std::move(this->getHolder()));
205  return holder;
206  }
207 
208  IHolder<ALLOC>* move(void*) override
209  {
210  throw CppRuntimeException("AnyHolder: Unexpected move call.");
211  }
212 
213  IHolder<ALLOC>* move(NoInitT, void*) override
214  {
215  throw CppRuntimeException("AnyHolder: Unexpected move call.");
216  }
217 
218  void destroy(const ALLOC& allocator) override
219  {
220  using AllocType = RebindAlloc<ALLOC, this_type>;
221  using AllocTraits = std::allocator_traits<AllocType>;
222 
223  AllocType typedAlloc = allocator;
224  AllocTraits::destroy(typedAlloc, this);
225  AllocTraits::deallocate(typedAlloc, this, 1);
226  }
227  };
228 
229  // Holder allocated in the in-place storage
230  template <typename T, typename ALLOC>
231  class NonHeapHolder : public HolderBase<T, ALLOC>
232  {
233  public:
234  using this_type = NonHeapHolder<T, ALLOC>;
235 
236  static this_type* create(void* storage)
237  {
238  return new (storage) this_type();
239  }
240 
241  IHolder<ALLOC>* clone(const ALLOC&) const override
242  {
243  throw CppRuntimeException("AnyHolder: Unexpected clone call.");
244  }
245 
246  IHolder<ALLOC>* clone(NoInitT, const ALLOC&) const override
247  {
248  throw CppRuntimeException("AnyHolder: Unexpected clone call.");
249  }
250 
251  IHolder<ALLOC>* clone(void* storage) const override
252  {
253  NonHeapHolder* holder = new (storage) NonHeapHolder();
254  holder->setHolder(this->getHolder());
255  return holder;
256  }
257 
258  IHolder<ALLOC>* clone(NoInitT, void* storage) const override
259  {
260  NonHeapHolder* holder = new (storage) NonHeapHolder();
261  holder->setHolder(NoInit, this->getHolder());
262  return holder;
263  }
264 
265  IHolder<ALLOC>* move(const ALLOC&) override
266  {
267  throw CppRuntimeException("AnyHolder: Unexpected move call.");
268  }
269 
270  IHolder<ALLOC>* move(NoInitT, const ALLOC&) override
271  {
272  throw CppRuntimeException("AnyHolder: Unexpected move call.");
273  }
274 
275  IHolder<ALLOC>* move(void* storage) override
276  {
277  NonHeapHolder* holder = new (storage) NonHeapHolder();
278  holder->setHolder(std::move(this->getHolder()));
279  return holder;
280  }
281 
282  IHolder<ALLOC>* move(NoInitT, void* storage) override
283  {
284  NonHeapHolder* holder = new (storage) NonHeapHolder();
285  holder->setHolder(NoInit, std::move(this->getHolder()));
286  return holder;
287  }
288 
289  void destroy(const ALLOC&) override
290  {
291  this->~NonHeapHolder();
292  }
293 
294  private:
295  NonHeapHolder() = default;
296  };
297 
298  template <typename ALLOC>
299  union UntypedHolder
300  {
301  // 2 * sizeof(void*) for T + sizeof(void*) for Holder's vptr
302  using MaxInPlaceType = std::aligned_storage<3 * sizeof(void*), alignof(void*)>::type;
303 
304  detail::IHolder<ALLOC>* heap;
305  MaxInPlaceType inPlace;
306  };
307 
308  template <typename T, typename ALLOC>
309  using has_non_heap_holder = std::integral_constant<bool,
310  sizeof(NonHeapHolder<T, ALLOC>) <= sizeof(typename UntypedHolder<ALLOC>::MaxInPlaceType) &&
311  std::is_nothrow_move_constructible<T>::value &&
312  alignof(T) <= alignof(typename UntypedHolder<ALLOC>::MaxInPlaceType)>;
313 } // namespace detail
314 
318 template <typename ALLOC = std::allocator<uint8_t>>
319 class AnyHolder : public AllocatorHolder<ALLOC>
320 {
321  using AllocTraits = std::allocator_traits<ALLOC>;
324 
325 public:
327  using allocator_type = ALLOC;
328 
332  AnyHolder() : AnyHolder(ALLOC())
333  {
334  }
335 
339  explicit AnyHolder(const ALLOC& allocator) :
340  AllocatorHolder<ALLOC>(allocator)
341  {
342  m_untypedHolder.heap = nullptr;
343  }
344 
350  template <typename T,
351  typename std::enable_if<!std::is_same<typename std::decay<T>::type, AnyHolder>::value &&
352  !std::is_same<typename std::decay<T>::type, ALLOC>::value, int>::type = 0>
353  explicit AnyHolder(T&& value, const ALLOC& allocator = ALLOC()) :
354  AllocatorHolder<ALLOC>(allocator)
355  {
356  m_untypedHolder.heap = nullptr;
357  set(std::forward<T>(value));
358  }
359 
365  template <typename T, typename std::enable_if<
366  !std::is_same<typename std::decay<T>::type, AnyHolder>::value, int>::type = 0>
367  explicit AnyHolder(NoInitT, T&& value, const ALLOC& allocator = ALLOC()) :
368  AllocatorHolder<ALLOC>(allocator)
369  {
370  m_untypedHolder.heap = nullptr;
371  set(NoInit, std::forward<T>(value));
372  }
373 
378  {
379  clearHolder();
380  }
381 
387  AnyHolder(const AnyHolder& other) :
388  AllocatorHolder<ALLOC>(
389  AllocTraits::select_on_container_copy_construction(other.get_allocator_ref()))
390  {
391  copy(other);
392  }
393 
399  AnyHolder(NoInitT, const AnyHolder& other) :
400  AllocatorHolder<ALLOC>(
401  AllocTraits::select_on_container_copy_construction(other.get_allocator_ref()))
402  {
403  copy(NoInit, other);
404  }
405 
412  AnyHolder(const AnyHolder& other, const ALLOC& allocator) : AllocatorHolder<ALLOC>(allocator)
413  {
414  copy(other);
415  }
416 
423  AnyHolder(NoInitT, const AnyHolder& other, const ALLOC& allocator) :
424  AllocatorHolder<ALLOC>(allocator)
425  {
426  copy(NoInit, other);
427  }
428 
437  {
438  if (this != &other)
439  {
440  // TODO: do not dealloc unless necessary
441  clearHolder();
442  if (AllocTraits::propagate_on_container_copy_assignment::value)
443  set_allocator(other.get_allocator_ref());
444  copy(other);
445  }
446 
447  return *this;
448  }
449 
457  AnyHolder& assign(NoInitT, const AnyHolder& other)
458  {
459  if (this != &other)
460  {
461  // TODO: do not dealloc unless necessary
462  clearHolder();
463  if (AllocTraits::propagate_on_container_copy_assignment::value)
464  set_allocator(other.get_allocator_ref());
465  copy(NoInit, other);
466  }
467 
468  return *this;
469  }
470 
476  AnyHolder(AnyHolder&& other) noexcept :
477  AllocatorHolder<ALLOC>(std::move(other.get_allocator_ref()))
478  {
479  move(std::move(other));
480  }
481 
487  AnyHolder(NoInitT, AnyHolder&& other) noexcept :
488  AllocatorHolder<ALLOC>(std::move(other.get_allocator_ref()))
489  {
490  move(NoInit, std::move(other));
491  }
492 
499  AnyHolder(AnyHolder&& other, const ALLOC& allocator) :
500  AllocatorHolder<ALLOC>(allocator)
501  {
502  move(std::move(other));
503  }
504 
511  AnyHolder(NoInitT, AnyHolder&& other, const ALLOC& allocator) :
512  AllocatorHolder<ALLOC>(allocator)
513  {
514  move(NoInit, std::move(other));
515  }
516 
525  {
526  if (this != &other)
527  {
528  clearHolder();
529  if (AllocTraits::propagate_on_container_move_assignment::value)
530  set_allocator(std::move(other.get_allocator_ref()));
531  move(std::move(other));
532  }
533 
534  return *this;
535  }
536 
544  AnyHolder& assign(NoInitT, AnyHolder&& other)
545  {
546  if (this != &other)
547  {
548  clearHolder();
549  if (AllocTraits::propagate_on_container_move_assignment::value)
550  set_allocator(std::move(other.get_allocator_ref()));
551  move(NoInit, std::move(other));
552  }
553 
554  return *this;
555  }
556 
564  template <typename T, typename
565  std::enable_if<!std::is_same<typename std::decay<T>::type, AnyHolder>::value, int>::type = 0>
566  AnyHolder& operator=(T&& value)
567  {
568  set(std::forward<T>(value));
569 
570  return *this;
571  }
572 
576  void reset()
577  {
578  clearHolder();
579  }
580 
586  template <typename T>
587  void set(T&& value)
588  {
589  createHolder<typename std::decay<T>::type>()->set(std::forward<T>(value));
590  }
591 
597  template <typename T>
598  void set(NoInitT, T&& value)
599  {
600  createHolder<typename std::decay<T>::type>()->set(NoInit, std::forward<T>(value));
601  }
602 
610  template <typename T>
611  T& get()
612  {
613  checkType<T>();
614  return getHolder<T>(detail::has_non_heap_holder<T, ALLOC>())->get();
615  }
616 
624  template <typename T>
625  const T& get() const
626  {
627  checkType<T>();
628  return getHolder<T>(detail::has_non_heap_holder<T, ALLOC>())->get();
629  }
630 
636  template <typename T>
637  bool isType() const
638  {
639  return hasHolder() && getUntypedHolder()->isType(detail::TypeIdHolder::get<T>());
640  }
641 
647  bool hasValue() const
648  {
649  return hasHolder();
650  }
651 
652 private:
653  void copy(const AnyHolder& other)
654  {
655  if (other.m_isInPlace)
656  {
657  other.getUntypedHolder()->clone(&m_untypedHolder.inPlace);
658  m_isInPlace = true;
659  }
660  else if (other.m_untypedHolder.heap != nullptr)
661  {
662  m_untypedHolder.heap = other.getUntypedHolder()->clone(get_allocator_ref());
663  }
664  else
665  {
666  m_untypedHolder.heap = nullptr;
667  }
668  }
669 
670  void copy(NoInitT, const AnyHolder& other)
671  {
672  if (other.m_isInPlace)
673  {
674  other.getUntypedHolder()->clone(NoInit, &m_untypedHolder.inPlace);
675  m_isInPlace = true;
676  }
677  else if (other.m_untypedHolder.heap != nullptr)
678  {
679  m_untypedHolder.heap = other.getUntypedHolder()->clone(NoInit,
680  get_allocator_ref());
681  }
682  else
683  {
684  m_untypedHolder.heap = nullptr;
685  }
686  }
687 
688  void move(AnyHolder&& other)
689  {
690  if (other.m_isInPlace)
691  {
692  other.getUntypedHolder()->move(&m_untypedHolder.inPlace);
693  m_isInPlace = true;
694  other.clearHolder();
695  }
696  else if (other.m_untypedHolder.heap != nullptr)
697  {
698  if (get_allocator_ref() == other.get_allocator_ref())
699  {
700  // take over the other's storage
701  m_untypedHolder.heap = other.m_untypedHolder.heap;
702  other.m_untypedHolder.heap = nullptr;
703  }
704  else
705  {
706  // cannot steal the storage, allocate our own and move the holder
707  m_untypedHolder.heap = other.getUntypedHolder()->move(get_allocator_ref());
708  other.clearHolder();
709  }
710  }
711  else
712  {
713  m_untypedHolder.heap = nullptr;
714  }
715  }
716 
717  void move(NoInitT, AnyHolder&& other)
718  {
719  if (other.m_isInPlace)
720  {
721  other.getUntypedHolder()->move(NoInit, &m_untypedHolder.inPlace);
722  m_isInPlace = true;
723  other.clearHolder();
724  }
725  else if (other.m_untypedHolder.heap != nullptr)
726  {
727  if (get_allocator_ref() == other.get_allocator_ref())
728  {
729  // take over the other's storage
730  m_untypedHolder.heap = other.m_untypedHolder.heap;
731  other.m_untypedHolder.heap = nullptr;
732  }
733  else
734  {
735  // cannot steal the storage, allocate our own and move the holder
736  m_untypedHolder.heap = other.getUntypedHolder()->move(NoInit,
737  get_allocator_ref());
738  other.clearHolder();
739  }
740  }
741  else
742  {
743  m_untypedHolder.heap = nullptr;
744  }
745  }
746 
747  void clearHolder()
748  {
749  if (hasHolder())
750  {
751  getUntypedHolder()->destroy(get_allocator_ref());
752  m_isInPlace = false;
753  m_untypedHolder.heap = nullptr;
754  }
755  }
756 
757  bool hasHolder() const
758  {
759  return (m_isInPlace || m_untypedHolder.heap != nullptr);
760  }
761 
762  template <typename T>
763  detail::HolderBase<T, ALLOC>* createHolder()
764  {
765  if (hasHolder())
766  {
767  if (getUntypedHolder()->isType(detail::TypeIdHolder::get<T>()))
768  return getHolder<T>(detail::has_non_heap_holder<T, ALLOC>());
769 
770  clearHolder();
771  }
772 
773  return createHolderImpl<T>(detail::has_non_heap_holder<T, ALLOC>());
774  }
775 
776  template <typename T>
777  detail::HolderBase<T, ALLOC>* createHolderImpl(std::true_type)
778  {
779  detail::NonHeapHolder<T, ALLOC>* holder =
780  detail::NonHeapHolder<T, ALLOC>::create(&m_untypedHolder.inPlace);
781  m_isInPlace = true;
782  return holder;
783  }
784 
785  template <typename T>
786  detail::HolderBase<T, ALLOC>* createHolderImpl(std::false_type)
787  {
788  detail::HeapHolder<T, ALLOC>* holder = detail::HeapHolder<T, ALLOC>::create(get_allocator_ref());
789  m_untypedHolder.heap = holder;
790  return holder;
791  }
792 
793  template <typename T>
794  void checkType() const
795  {
796  if (!isType<T>())
797  throwBadType();
798  }
799 
801  void throwBadType() const
802  {
803  throw CppRuntimeException("Bad type in AnyHolder");
804  }
805 
806  template <typename T>
807  detail::HeapHolder<T, ALLOC>* getHeapHolder()
808  {
809  return static_cast<detail::HeapHolder<T, ALLOC>*>(m_untypedHolder.heap);
810  }
811 
812  template <typename T>
813  const detail::HeapHolder<T, ALLOC>* getHeapHolder() const
814  {
815  return static_cast<detail::HeapHolder<T, ALLOC>*>(m_untypedHolder.heap);
816  }
817 
818  template <typename T>
819  detail::NonHeapHolder<T, ALLOC>* getInplaceHolder()
820  {
821  return reinterpret_cast<detail::NonHeapHolder<T, ALLOC>*>(&m_untypedHolder.inPlace);
822  }
823 
824  template <typename T>
825  const detail::NonHeapHolder<T, ALLOC>* getInplaceHolder() const
826  {
827  return reinterpret_cast<const detail::NonHeapHolder<T, ALLOC>*>(&m_untypedHolder.inPlace);
828  }
829 
830  template <typename T>
831  detail::HolderBase<T, ALLOC>* getHolder(std::true_type)
832  {
833  return static_cast<detail::HolderBase<T, ALLOC>*>(getInplaceHolder<T>());
834  }
835 
836  template <typename T>
837  detail::HolderBase<T, ALLOC>* getHolder(std::false_type)
838  {
839  return static_cast<detail::HolderBase<T, ALLOC>*>(getHeapHolder<T>());
840  }
841 
842  template <typename T>
843  const detail::HolderBase<T, ALLOC>* getHolder(std::true_type) const
844  {
845  return static_cast<const detail::HolderBase<T, ALLOC>*>(getInplaceHolder<T>());
846  }
847 
848  template <typename T>
849  const detail::HolderBase<T, ALLOC>* getHolder(std::false_type) const
850  {
851  return static_cast<const detail::HolderBase<T, ALLOC>*>(getHeapHolder<T>());
852  }
853 
854  detail::IHolder<ALLOC>* getUntypedHolder()
855  {
856  return (m_isInPlace) ?
857  reinterpret_cast<detail::IHolder<ALLOC>*>(&m_untypedHolder.inPlace) :
858  m_untypedHolder.heap;
859  }
860 
861  const detail::IHolder<ALLOC>* getUntypedHolder() const
862  {
863  return (m_isInPlace) ?
864  reinterpret_cast<const detail::IHolder<ALLOC>*>(&m_untypedHolder.inPlace) :
865  m_untypedHolder.heap;
866  }
867 
868  detail::UntypedHolder<ALLOC> m_untypedHolder;
869  bool m_isInPlace = false;
870 };
871 
872 } // namespace zserio
873 
874 #endif // ifndef ZSERIO_ANY_HOLDER_H_INC
AnyHolder(AnyHolder &&other) noexcept
Definition: AnyHolder.h:476
AnyHolder(AnyHolder &&other, const ALLOC &allocator)
Definition: AnyHolder.h:499
AnyHolder & operator=(T &&value)
Definition: AnyHolder.h:566
constexpr NoInitT NoInit
Definition: NoInit.h:18
AnyHolder(const ALLOC &allocator)
Definition: AnyHolder.h:339
AnyHolder(NoInitT, T &&value, const ALLOC &allocator=ALLOC())
Definition: AnyHolder.h:367
AnyHolder & assign(NoInitT, AnyHolder &&other)
Definition: AnyHolder.h:544
AnyHolder(T &&value, const ALLOC &allocator=ALLOC())
Definition: AnyHolder.h:353
allocator_type & get_allocator_ref()
AnyHolder & operator=(const AnyHolder &other)
Definition: AnyHolder.h:436
bool isType() const
Definition: AnyHolder.h:637
AnyHolder(NoInitT, const AnyHolder &other)
Definition: AnyHolder.h:399
AnyHolder & operator=(AnyHolder &&other)
Definition: AnyHolder.h:524
bool hasValue() const
Definition: AnyHolder.h:647
AnyHolder(NoInitT, const AnyHolder &other, const ALLOC &allocator)
Definition: AnyHolder.h:423
AnyHolder(NoInitT, AnyHolder &&other) noexcept
Definition: AnyHolder.h:487
AnyHolder(const AnyHolder &other, const ALLOC &allocator)
Definition: AnyHolder.h:412
AnyHolder(const AnyHolder &other)
Definition: AnyHolder.h:387
AnyHolder(NoInitT, AnyHolder &&other, const ALLOC &allocator)
Definition: AnyHolder.h:511
AnyHolder & assign(NoInitT, const AnyHolder &other)
Definition: AnyHolder.h:457