Skip to content

Commit 97fafb9

Browse files
committed
StoredRange can store an optionally-deleted unique_ptr
* Also add some libmesh_asserts in StoredRange::reset() to catch the case where a range is reset() but the _objs pointer was not initialized. * Use lambdas to define the custom deleter. The decision to delete/not is made at construction time, and does not change during the object's lifetime. * One thing I am not 100% happy with is that we still need to call 'new' when allocating the class unique_ptr, since one cannot really use std::make_unique when a custom deleter is employed. https://stackoverflow.com/questions/21788066/using-stdmake-unique-with-a-custom-deleter * Use ptr_type typedef for improved readability * Add required C++ includes.
1 parent efa6ffb commit 97fafb9

1 file changed

Lines changed: 22 additions & 25 deletions

File tree

include/geom/stored_range.h

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525

2626
// C++ includes
2727
#include <vector>
28+
#include <memory> // std::unique_ptr
29+
#include <functional> // std::function
2830

2931
namespace libMesh
3032
{
@@ -55,7 +57,9 @@ class StoredRange
5557
/**
5658
* Allows an \p StoredRange to behave like an STL container.
5759
*/
58-
typedef typename std::vector<object_type>::const_iterator const_iterator;
60+
typedef typename std::vector<object_type> vec_type;
61+
typedef typename vec_type::const_iterator const_iterator;
62+
typedef typename std::unique_ptr<vec_type, std::function<void (vec_type *)>> ptr_type;
5963

6064
/**
6165
* Constructor. Optionally takes the \p grainsize parameter, which is the
@@ -68,8 +72,7 @@ class StoredRange
6872
_last(),
6973
_first(),
7074
_grainsize(new_grainsize),
71-
_objs(new std::vector<object_type>()),
72-
_should_release(true)
75+
_objs(ptr_type(new vec_type(), [](vec_type * p){delete p;}))
7376
{}
7477

7578
/**
@@ -86,8 +89,7 @@ class StoredRange
8689
_last(),
8790
_first(),
8891
_grainsize(new_grainsize),
89-
_objs(new std::vector<object_type>()),
90-
_should_release(true)
92+
_objs(ptr_type(new vec_type(), [](vec_type * p){delete p;}))
9193
{
9294
this->reset(first, last);
9395
}
@@ -99,19 +101,17 @@ class StoredRange
99101
* execution.
100102
*
101103
* \note The std::vector passed in here MUST live for the
102-
* lifetime of this StoredRange!
103-
*
104-
* \todo This should be a std::shared_ptr in the future!
104+
* lifetime of this StoredRange! We are not responsible for
105+
* deleting this pointer.
105106
*/
106-
StoredRange (std::vector<object_type> * objs,
107+
StoredRange (vec_type * objs,
107108
const unsigned int new_grainsize = 1000) :
108109
_end(objs->end()),
109110
_begin(objs->begin()),
110111
_last(objs->size()),
111112
_first(0),
112113
_grainsize(new_grainsize),
113-
_objs(objs),
114-
_should_release(false)
114+
_objs(ptr_type(objs, [](vec_type *){/*don't delete*/}))
115115
{
116116
}
117117

@@ -134,8 +134,7 @@ class StoredRange
134134
_last(er._last),
135135
_first(er._first),
136136
_grainsize(er._grainsize),
137-
_objs(nullptr),
138-
_should_release(false)
137+
_objs(nullptr)
139138
{
140139
// specifically, do *not* copy the vector
141140
}
@@ -165,8 +164,7 @@ class StoredRange
165164
_last(0), // Initialize these in a moment
166165
_first(0),
167166
_grainsize(er._grainsize),
168-
_objs(nullptr),
169-
_should_release(false)
167+
_objs(nullptr)
170168
{
171169
// specifically, do *not* copy the vector
172170

@@ -185,8 +183,7 @@ class StoredRange
185183
_last(r._last),
186184
_first(r._first),
187185
_grainsize(r._grainsize),
188-
_objs(nullptr),
189-
_should_release(false)
186+
_objs(nullptr)
190187
{
191188
const_iterator
192189
beginning = r._begin,
@@ -206,11 +203,7 @@ class StoredRange
206203
/**
207204
* Destructor. Releases the object array if we created it.
208205
*/
209-
~StoredRange ()
210-
{
211-
if (_should_release)
212-
delete _objs;
213-
}
206+
~StoredRange () = default;
214207

215208
/**
216209
* Resets the \p StoredRange to contain [first,last).
@@ -222,6 +215,9 @@ class StoredRange
222215
reset (const iterator_type & first,
223216
const iterator_type & last)
224217
{
218+
// _objs must be initialized in order to call reset()
219+
libmesh_assert(_objs);
220+
225221
_objs->clear();
226222

227223
for (iterator_type it=first; it!=last; ++it)
@@ -246,6 +242,9 @@ class StoredRange
246242
*/
247243
StoredRange<iterator_type, object_type> & reset ()
248244
{
245+
// _objs must be initialized in order to call reset()
246+
libmesh_assert(_objs);
247+
249248
_begin = _objs->begin();
250249
_end = _objs->end();
251250

@@ -313,9 +312,7 @@ class StoredRange
313312
std::size_t _first;
314313
std::size_t _grainsize;
315314

316-
// TODO: Make this a std::shared_ptr in the future!
317-
std::vector<object_type> * _objs;
318-
bool _should_release;
315+
ptr_type _objs;
319316
};
320317

321318
} // namespace libMesh

0 commit comments

Comments
 (0)