dune-functions  2.7.0
polymorphicsmallobject.hh
Go to the documentation of this file.
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 
8 #include <dune/common/std/type_traits.hh>
9 #include <dune/common/hybridutilities.hh>
10 
11 namespace Dune {
12 namespace Functions {
13 
14 
45 template<class Base, size_t bufferSize>
47 {
48 public:
49 
52  p_(nullptr)
53  {}
54 
61  template<class Derived>
62  PolymorphicSmallObject(Derived&& derived)
63  {
64  using namespace Dune::Hybrid;
65  auto useBuffer = Dune::Std::bool_constant<(sizeof(Derived)<bufferSize)>();
66  ifElse(useBuffer, [&](auto id) {
67  p_ = new (buffer_) Derived(std::forward<Derived>(derived));
68  }, [&](auto id) {
69  p_ = new Derived(std::forward<Derived>(derived));
70  });
71  }
72 
75  {
76  moveToWrappedObject(std::move(other));
77  }
78 
81  {
82  copyToWrappedObject(other);
83  }
84 
87  {
88  destroyWrappedObject();
89  }
90 
93  {
94  destroyWrappedObject();
95  copyToWrappedObject(other);
96  return *this;
97  }
98 
101  {
102  destroyWrappedObject();
103  moveToWrappedObject(std::move(other));
104  return *this;
105  }
106 
108  explicit operator bool() const
109  {
110  return p_;
111  }
112 
114  bool bufferUsed() const
115  {
116  return ((void*) (p_) == (void*)(&buffer_));
117  }
118 
120  const Base& get() const
121  {
122  return *p_;
123  }
124 
126  Base& get()
127  {
128  return *p_;
129  }
130 
131 private:
132 
133  void destroyWrappedObject()
134  {
135  if (operator bool())
136  {
137  if (bufferUsed())
138  p_->~Base();
139  else
140  delete p_;
141  }
142  }
143 
144  void moveToWrappedObject(PolymorphicSmallObject&& other)
145  {
146  if (other.bufferUsed())
147  p_ = other.p_->move(buffer_);
148  else
149  {
150  // We don't need to check for &other_!=this, because you can't
151  // have an rvalue to *this and call it's assignment/constructor
152  // at the same time. (Despite trying to shot yourself in the foot
153  // with std::move explicitly.)
154 
155  // Take ownership of allocated object
156  p_ = other.p_;
157 
158  // Leave pointer in a clean state to avoid double freeing it.
159  other.p_ = 0;
160  }
161  }
162 
163  void copyToWrappedObject(const PolymorphicSmallObject& other)
164  {
165  if (&other!=this)
166  {
167  if (other.bufferUsed())
168  p_ = other.p_->clone(buffer_);
169  else
170  p_ = other.p_->clone();
171  }
172  }
173 
174  alignas(Base) char buffer_[bufferSize];
175  Base* p_;
176 };
177 
178 
179 } // namespace Functions
180 } // namespace Dune
181 
182 #endif // DUNE_FUNCTIONS_COMMON_POLYMORPHICSMALLOBJECT_HH
Dune::Functions::PolymorphicSmallObject::PolymorphicSmallObject
PolymorphicSmallObject(PolymorphicSmallObject &&other)
Move constructor from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:74
Dune::Functions::PolymorphicSmallObject::bufferUsed
bool bufferUsed() const
Check if object is stored in internal stack buffer.
Definition: polymorphicsmallobject.hh:114
Dune::Functions::PolymorphicSmallObject::operator=
PolymorphicSmallObject & operator=(PolymorphicSmallObject &&other)
Move assignment from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:100
Dune::Functions::PolymorphicSmallObject
A wrapper providing small object optimization with polymorphic types.
Definition: polymorphicsmallobject.hh:46
Dune::Functions::PolymorphicSmallObject::~PolymorphicSmallObject
~PolymorphicSmallObject()
Destructor.
Definition: polymorphicsmallobject.hh:86
Dune::Functions::PolymorphicSmallObject::PolymorphicSmallObject
PolymorphicSmallObject()
Default constructor.
Definition: polymorphicsmallobject.hh:51
Dune::Functions::PolymorphicSmallObject::get
const Base & get() const
Obtain reference to stored object.
Definition: polymorphicsmallobject.hh:120
Dune::Functions::PolymorphicSmallObject::PolymorphicSmallObject
PolymorphicSmallObject(const PolymorphicSmallObject &other)
Copy constructor from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:80
Dune
Definition: polynomial.hh:10
Dune::Functions::PolymorphicSmallObject::operator=
PolymorphicSmallObject & operator=(const PolymorphicSmallObject &other)
Copy assignment from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:92
Dune::Functions::PolymorphicSmallObject::get
Base & get()
Obtain mutable reference to stored object.
Definition: polymorphicsmallobject.hh:126
Dune::Functions::PolymorphicSmallObject::PolymorphicSmallObject
PolymorphicSmallObject(Derived &&derived)
Construct from object.
Definition: polymorphicsmallobject.hh:62