DUNE PDELab (2.7)

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#include <dune/common/std/type_traits.hh>
10#include <dune/common/hybridutilities.hh>
11
12namespace Dune {
13namespace Functions {
14
15
46template<class Base, size_t bufferSize>
48{
49public:
50
53 p_(nullptr)
54 {}
55
62 template<class Derived,
63 typename std::enable_if<std::is_base_of<Base, std::remove_cv_t<
64 std::remove_reference_t<Derived>>>::value, int>::type = 0>
65 PolymorphicSmallObject(Derived&& derived)
66 {
67 using namespace Dune::Hybrid;
69 ifElse(useBuffer, [&](auto id) {
70 p_ = new (&buffer_) Derived(std::forward<Derived>(derived));
71 }, [&](auto id) {
72 p_ = new Derived(std::forward<Derived>(derived));
73 });
74 }
75
78 {
79 moveToWrappedObject(std::move(other));
80 }
81
84 {
85 copyToWrappedObject(other);
86 }
87
90 {
91 destroyWrappedObject();
92 }
93
96 {
97 if (&other!=this)
98 {
99 destroyWrappedObject();
100 copyToWrappedObject(other);
101 }
102 return *this;
103 }
104
107 {
108 destroyWrappedObject();
109 moveToWrappedObject(std::move(other));
110 return *this;
111 }
112
114 explicit operator bool() const
115 {
116 return p_;
117 }
118
120 bool bufferUsed() const
121 {
122 return ((void*) (p_) == (void*)(&buffer_));
123 }
124
126 const Base& get() const
127 {
128 return *p_;
129 }
130
132 Base& get()
133 {
134 return *p_;
135 }
136
137private:
138
139 void destroyWrappedObject()
140 {
141 if (operator bool())
142 {
143 if (bufferUsed())
144 p_->~Base();
145 else
146 delete p_;
147 }
148 }
149
150 void moveToWrappedObject(PolymorphicSmallObject&& other)
151 {
152 if (other.bufferUsed())
153 p_ = other.p_->move(&buffer_);
154 else
155 {
156 // We don't need to check for &other_!=this, because you can't
157 // have an rvalue to *this and call it's assignment/constructor
158 // at the same time. (Despite trying to shoot yourself in the foot
159 // with std::move explicitly.)
160
161 // Take ownership of allocated object
162 p_ = other.p_;
163
164 // Leave pointer in a clean state to avoid double freeing it.
165 other.p_ = 0;
166 }
167 }
168
169 void copyToWrappedObject(const PolymorphicSmallObject& other)
170 {
171 if (other.bufferUsed())
172 p_ = other.p_->clone(&buffer_);
173 else
174 p_ = other.p_->clone();
175 }
176
177 std::aligned_storage_t<bufferSize> buffer_;
178 Base* p_;
179};
180
181
182} // namespace Functions
183} // namespace Dune
184
185#endif // DUNE_FUNCTIONS_COMMON_POLYMORPHICSMALLOBJECT_HH
A wrapper providing small object optimization with polymorphic types.
Definition: polymorphicsmallobject.hh:48
const Base & get() const
Obtain reference to stored object.
Definition: polymorphicsmallobject.hh:126
bool bufferUsed() const
Check if object is stored in internal stack buffer.
Definition: polymorphicsmallobject.hh:120
PolymorphicSmallObject(Derived &&derived)
Construct from object.
Definition: polymorphicsmallobject.hh:65
PolymorphicSmallObject & operator=(const PolymorphicSmallObject &other)
Copy assignment from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:95
PolymorphicSmallObject(const PolymorphicSmallObject &other)
Copy constructor from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:83
~PolymorphicSmallObject()
Destructor.
Definition: polymorphicsmallobject.hh:89
PolymorphicSmallObject(PolymorphicSmallObject &&other)
Move constructor from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:77
PolymorphicSmallObject()
Default constructor.
Definition: polymorphicsmallobject.hh:52
PolymorphicSmallObject & operator=(PolymorphicSmallObject &&other)
Move assignment from other PolymorphicSmallObject.
Definition: polymorphicsmallobject.hh:106
Base & get()
Obtain mutable reference to stored object.
Definition: polymorphicsmallobject.hh:132
std::integral_constant< bool, value > bool_constant
A template alias for std::integral_constant<bool, value>
Definition: type_traits.hh:118
decltype(auto) ifElse(const Condition &condition, IfFunc &&ifFunc, ElseFunc &&elseFunc)
A conditional expression.
Definition: hybridutilities.hh:355
Dune namespace.
Definition: alignedallocator.hh:14
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Jul 15, 22:36, 2024)