Dune Core Modules (2.9.0)

polymorphicsmallobject.hh
1 // -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 // vi: set et ts=4 sw=2 sts=2:
3 #ifndef DUNE_FUNCTIONS_COMMON_POLYMORPHICSMALLOBJECT_HH
4 #define DUNE_FUNCTIONS_COMMON_POLYMORPHICSMALLOBJECT_HH
5 
6 #include <utility>
7 #include <type_traits>
8 
9 namespace Dune {
10 namespace Functions {
11 
12 
43 template<class Base, size_t bufferSize>
45 {
46 public:
47 
50  p_(nullptr)
51  {}
52 
59  template<class Derived,
60  typename std::enable_if<std::is_base_of<Base, std::remove_cv_t<
61  std::remove_reference_t<Derived>>>::value, int>::type = 0>
62  PolymorphicSmallObject(Derived&& derived)
63  {
64  constexpr bool useBuffer = sizeof(Derived) <= bufferSize;
65  if constexpr (useBuffer) {
66  p_ = new (&buffer_) Derived(std::forward<Derived>(derived));
67  } else {
68  p_ = new Derived(std::forward<Derived>(derived));
69  }
70  }
71 
74  {
75  moveToWrappedObject(std::move(other));
76  }
77 
80  {
81  copyToWrappedObject(other);
82  }
83 
86  {
87  destroyWrappedObject();
88  }
89 
92  {
93  if (&other!=this)
94  {
95  destroyWrappedObject();
96  copyToWrappedObject(other);
97  }
98  return *this;
99  }
100 
103  {
104  destroyWrappedObject();
105  moveToWrappedObject(std::move(other));
106  return *this;
107  }
108 
110  explicit operator bool() const
111  {
112  return p_;
113  }
114 
116  bool bufferUsed() const
117  {
118  return ((void*) (p_) == (void*)(&buffer_));
119  }
120 
122  const Base& get() const
123  {
124  return *p_;
125  }
126 
128  Base& get()
129  {
130  return *p_;
131  }
132 
133 private:
134 
135  void destroyWrappedObject() noexcept
136  {
137  if (operator bool())
138  {
139  if (bufferUsed())
140  p_->~Base();
141  else
142  delete p_;
143  }
144  }
145 
146  void moveToWrappedObject(PolymorphicSmallObject&& other) noexcept
147  {
148  if (other.bufferUsed())
149  p_ = other.p_->move(&buffer_);
150  else
151  {
152  // We don't need to check for &other_!=this, because you can't
153  // have an rvalue to *this and call it's assignment/constructor
154  // at the same time. (Despite trying to shoot yourself in the foot
155  // with std::move explicitly.)
156 
157  // Take ownership of allocated object
158  p_ = other.p_;
159 
160  // Leave pointer in a clean state to avoid double freeing it.
161  other.p_ = 0;
162  }
163  }
164 
165  void copyToWrappedObject(const PolymorphicSmallObject& other)
166  {
167  if (other.bufferUsed())
168  p_ = other.p_->clone(&buffer_);
169  else
170  p_ = other.p_->clone();
171  }
172 
173  std::aligned_storage_t<bufferSize> buffer_;
174  Base* p_;
175 };
176 
177 
178 } // namespace Functions
179 } // namespace Dune
180 
181 #endif // DUNE_FUNCTIONS_COMMON_POLYMORPHICSMALLOBJECT_HH
A wrapper providing small object optimization with polymorphic types.
Definition: polymorphicsmallobject.hh:45
PolymorphicSmallObject & operator=(PolymorphicSmallObject &&other) noexcept
Move assignment from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:102
bool bufferUsed() const
Check if object is stored in internal stack buffer.
Definition: polymorphicsmallobject.hh:116
PolymorphicSmallObject(Derived &&derived)
Construct from object.
Definition: polymorphicsmallobject.hh:62
PolymorphicSmallObject(PolymorphicSmallObject &&other) noexcept
Move constructor from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:73
Base & get()
Obtain mutable reference to stored object.
Definition: polymorphicsmallobject.hh:128
PolymorphicSmallObject & operator=(const PolymorphicSmallObject &other)
Copy assignment from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:91
PolymorphicSmallObject(const PolymorphicSmallObject &other)
Copy constructor from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:79
~PolymorphicSmallObject()
Destructor.
Definition: polymorphicsmallobject.hh:85
const Base & get() const
Obtain reference to stored object.
Definition: polymorphicsmallobject.hh:122
PolymorphicSmallObject()
Default constructor.
Definition: polymorphicsmallobject.hh:49
Dune namespace.
Definition: alignedallocator.hh:13
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.80.0 (May 16, 22:29, 2024)