Loading...
Searching...
No Matches
proxyVector.hpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit is free software: you can redistribute it and/or modify it
12 * under the terms of the GNU Lesser General Public License v3 (LGPL)
13 * as published by the Free Software Foundation.
14 *
15 * bitpit is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#ifndef __BITPIT_PROXY_VECTOR_HPP__
26#define __BITPIT_PROXY_VECTOR_HPP__
27
28#define __PXI_POINTER_TYPE__ \
29 typename std::conditional<std::is_const<value_t>::value, \
30 typename container_t::const_pointer, \
31 typename container_t::pointer>::type
32
33#define __PXI_REFERENCE_TYPE__ \
34 typename std::conditional<std::is_const<value_t>::value, \
35 typename container_t::const_reference, \
36 typename container_t::reference>::type
37
38#define __PXI_REFERENCE__ typename ProxyVectorIterator<value_t, container_t>::reference
39#define __PXI_POINTER__ typename ProxyVectorIterator<value_t, container_t>::pointer
40
41#define __PXV_REFERENCE__ typename ProxyVector<value_t, thread_safe>::reference
42#define __PXV_CONST_REFERENCE__ typename ProxyVector<value_t, thread_safe>::const_reference
43#define __PXV_POINTER__ typename ProxyVector<value_t, thread_safe>::pointer
44#define __PXV_CONST_POINTER__ typename ProxyVector<value_t, thread_safe>::const_pointer
45#define __PXV_STORAGE_POINTER__ typename ProxyVector<value_t, thread_safe>::storage_pointer
46#define __PXV_STORAGE_CONST_POINTER__ typename ProxyVector<value_t, thread_safe>::storage_const_pointer
47#define __PXV_ITERATOR__ typename ProxyVector<value_t, thread_safe>::iterator
48#define __PXV_CONST_ITERATOR__ typename ProxyVector<value_t, thread_safe>::const_iterator
49
50#include <cassert>
51#include <memory>
52#include <vector>
53
54#include "bitpit_common.hpp"
55
56namespace bitpit {
57
58template<typename PXV_value_t, bool PXV_thread_safe>
59class ProxyVector;
60
68template<typename value_t, typename container_t>
70 : public std::iterator<std::random_access_iterator_tag, value_t, std::ptrdiff_t, __PXI_POINTER_TYPE__, __PXI_REFERENCE_TYPE__>
71{
72
73template<typename PXV_value_t, bool PXV_thread_safe>
74friend class ProxyVector;
75
76friend class ProxyVectorIterator<typename std::add_const<value_t>::type, container_t>;
77
78public:
82 typedef std::bidirectional_iterator_tag iterator_category;
83
87 typedef value_t value_type;
88
92 typedef std::ptrdiff_t difference_type;
93
97 typedef __PXI_POINTER_TYPE__ pointer;
98
102 typedef __PXI_REFERENCE_TYPE__ reference;
103
104 // Constructors
106
107 template<typename other_value_t, typename std::enable_if<std::is_const<value_t>::value && !std::is_const<other_value_t>::value && std::is_same<other_value_t, typename std::remove_cv<value_t>::type>::value, int>::type = 0>
108 ProxyVectorIterator(const ProxyVectorIterator<other_value_t, container_t> &other);
109
110 // General methods
111 void swap(ProxyVectorIterator& other) noexcept;
112
113 // Operators
114 ProxyVectorIterator& operator++();
115 ProxyVectorIterator operator++(int);
116
117 ProxyVectorIterator& operator--();
118 ProxyVectorIterator operator--(int);
119
120 ProxyVectorIterator& operator+=(int increment);
121
122 std::size_t operator-(const ProxyVectorIterator &other);
123
124 __PXI_REFERENCE__ operator*() const;
125 __PXI_POINTER__ operator->() const;
126
127 template<typename other_value_t, typename std::enable_if<std::is_const<value_t>::value && !std::is_const<other_value_t>::value && std::is_same<other_value_t, typename std::remove_cv<value_t>::type>::value, int>::type = 0>
128 ProxyVectorIterator & operator=(const ProxyVectorIterator<other_value_t, container_t> &other);
129
133 bool operator==(const ProxyVectorIterator &other) const
134 {
135 return (m_position == other.m_position);
136 }
137
141 bool operator!=(const ProxyVectorIterator &other) const
142 {
143 return (m_position != other.m_position);
144 }
145
146private:
150 __PXI_POINTER__ m_position;
151
152 // Constructors
153 explicit ProxyVectorIterator(__PXI_POINTER__ position);
154
155};
156
164template<typename pointer_t, typename const_pointer_t>
166{
167
168public:
169 virtual ~ProxyVectorStorageInterface() = default;
170
171 virtual bool empty() const = 0;
172 virtual std::size_t size() const = 0;
173
174 virtual pointer_t data() = 0;
175 virtual const_pointer_t data() const = 0;
176
177 virtual void resize(std::size_t size) = 0;
178
179};
180
189template<typename value_t, typename pointer_t = value_t *, typename const_pointer_t = const value_t *>
190class ProxyVectorDummyStorage : public ProxyVectorStorageInterface<pointer_t, const_pointer_t>
191{
192
193template<typename PXV_value_t, bool PXV_thread_safe>
194friend class ProxyVector;
195
196public:
197 typedef pointer_t pointer;
198 typedef const_pointer_t const_pointer;
199
200 void swap(ProxyVectorDummyStorage &other) noexcept;
201
202 pointer data() override;
203 const_pointer data() const override;
204
205 bool empty() const override;
206 std::size_t size() const override;
207
208 void resize(std::size_t size) override;
209
210protected:
211 ProxyVectorDummyStorage(std::size_t size = 0);
212
213};
214
224template<typename value_t, typename container_t, bool thread_safe>
225class ProxyVectorStorage : public ProxyVectorStorageInterface<typename container_t::pointer, typename container_t::const_pointer>
226{
227
228template<typename PXV_value_t, bool PXV_thread_safe>
229friend class ProxyVector;
230
231public:
232 typedef container_t container_type;
233
234 typedef typename container_t::pointer pointer;
235 typedef typename container_t::const_pointer const_pointer;
236
237 ~ProxyVectorStorage() override;
238
239 void swap(ProxyVectorStorage &other) noexcept;
240
241 container_t * container(bool forceCreation);
242 const container_t * container(bool forceCreation) const;
243
244 pointer data() override;
245 const_pointer data() const override;
246
247 bool empty() const override;
248 std::size_t size() const override;
249
250 void resize(std::size_t size) override;
251
252protected:
253 ProxyVectorStorage(std::size_t size = 0);
255 ProxyVectorStorage(ProxyVectorStorage &&other) = default;
256
259
260private:
261 static const int MEMORY_POOL_VECTOR_COUNT = 10;
262 static const int MEMORY_POOL_MAX_CAPACITY = 128;
263
264 static std::vector<std::unique_ptr<container_t>> m_containerPool;
265
266 std::unique_ptr<container_t> createContainer(std::size_t size, bool allowEmpty);
267 std::unique_ptr<container_t> createContainer(const std::unique_ptr<container_t> &source, bool allowEmpty);
268 void destroyContainer(std::unique_ptr<container_t> *container);
269
270 std::unique_ptr<container_t> m_container;
271
272};
273
291template<typename value_t, bool thread_safe = false>
293{
294
295private:
296 typedef typename std::remove_cv<value_t>::type value_no_cv_t;
297
298public:
302 typedef std::vector<value_no_cv_t> container_type;
303
307 typedef value_t value_type;
308
313
318
322 typedef
323 typename std::conditional<std::is_const<value_t>::value,
324 typename container_type::const_pointer,
325 typename container_type::pointer>::type
327
331 typedef typename container_type::const_pointer const_pointer;
332
336 typedef typename container_type::pointer storage_pointer;
337
341 typedef typename container_type::const_pointer storage_const_pointer;
342
346 typedef
347 typename std::conditional<std::is_const<value_t>::value,
348 typename container_type::const_reference,
349 typename container_type::reference>::type
351
355 typedef typename container_type::const_reference const_reference;
356
360 static constexpr __PXV_POINTER__ INTERNAL_STORAGE = nullptr;
361
362 ProxyVector();
363 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
364 ProxyVector(std::size_t size);
365 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
366 ProxyVector(__PXV_POINTER__ data, std::size_t size);
367 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
368 ProxyVector(std::size_t size, std::size_t capacity);
369 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
370 ProxyVector(__PXV_POINTER__ data, std::size_t size, std::size_t capacity);
371 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
372 ProxyVector(__PXV_POINTER__ data, std::size_t size);
373
374 ProxyVector(const ProxyVector &other);
375 ProxyVector(ProxyVector &&other);
376
377 ProxyVector & operator=(const ProxyVector &other);
379
380 void swap(ProxyVector &other);
381
382 bool empty() const;
383 std::size_t size() const;
384
385 bool operator==(const ProxyVector &other) const;
386
387 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
388 void set(__PXV_POINTER__ data, std::size_t size);
389 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
390 void set(__PXV_POINTER__ data, std::size_t size, std::size_t capacity);
391 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
392 void set(__PXV_POINTER__ data, std::size_t size);
393
394 __PXV_STORAGE_POINTER__ storedData() noexcept;
395 __PXV_STORAGE_CONST_POINTER__ storedData() const noexcept;
396
397 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
398 container_type * storedDataContainer(bool forceCreation = false);
399 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
400 const container_type * storedDataContainer(bool forceCreation = false) const;
401
402 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
403 __PXV_POINTER__ data() noexcept;
404 __PXV_CONST_POINTER__ data() const noexcept;
405
406 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
407 __PXV_REFERENCE__ operator[](std::size_t n);
408 __PXV_CONST_REFERENCE__ operator[](std::size_t n) const;
409
410 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
411 __PXV_REFERENCE__ at(std::size_t n);
412 __PXV_CONST_REFERENCE__ at(std::size_t n) const;
413
414 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
415 __PXV_REFERENCE__ front();
416 __PXV_CONST_REFERENCE__ front() const;
417
418 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
419 __PXV_REFERENCE__ back();
420 __PXV_CONST_REFERENCE__ back() const;
421
422 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
423 __PXV_ITERATOR__ begin();
424 __PXV_CONST_ITERATOR__ begin() const;
425
426 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
427 __PXV_ITERATOR__ end();
428 __PXV_CONST_ITERATOR__ end() const;
429
430 __PXV_CONST_ITERATOR__ cbegin();
431 __PXV_CONST_ITERATOR__ cend();
432
433private:
437 typedef
438 typename std::conditional<std::is_const<value_t>::value,
439 ProxyVectorStorage<value_no_cv_t, container_type, thread_safe>,
440 ProxyVectorDummyStorage<value_no_cv_t>>::type
441 storage_t;
442
443 storage_t m_storage;
444
445 std::size_t m_size;
446 __PXV_POINTER__ m_data;
447
448};
449
450// Constant proxy vector
451template<typename value_t, bool thread_safe = false>
452using ConstProxyVector = ProxyVector<const value_t, thread_safe>;
453
454}
455
456// Include the implementation
457#include "proxyVector.tpp"
458
459namespace bitpit{
460
461// Some commonly used ProxyVectors are instantiated explicitly
462extern template class ProxyVector<int, true>;
463extern template class ProxyVector<long, true>;
464extern template class ProxyVector<double, true>;
465
466extern template class ProxyVector<int, false>;
467extern template class ProxyVector<long, false>;
468extern template class ProxyVector<double, false>;
469
470extern template class ProxyVector<const int, true>;
471extern template class ProxyVector<const long, true>;
472extern template class ProxyVector<const double, true>;
473
474extern template class ProxyVector<const int, false>;
475extern template class ProxyVector<const long, false>;
476extern template class ProxyVector<const double, false>;
477
478}
479
480#endif
Metafunction for generating ProxyVector dummy storages.
std::size_t size() const override
void resize(std::size_t size) override
void swap(ProxyVectorDummyStorage &other) noexcept
bool empty() const override
ProxyVectorDummyStorage(std::size_t size=0)
Iterator for the class ProxyVector.
__PXI_POINTER_TYPE__ pointer
bool operator!=(const ProxyVectorIterator &other) const
std::bidirectional_iterator_tag iterator_category
__PXI_REFERENCE_TYPE__ reference
void swap(ProxyVectorIterator &other) noexcept
Interface for ProxyVector storages.
Metafunction for generating ProxyVector storages.
ProxyVectorStorage(std::size_t size=0)
ProxyVectorStorage & operator=(const ProxyVectorStorage &other)
void swap(ProxyVectorStorage &other) noexcept
container_t * container(bool forceCreation)
pointer data() override
bool empty() const override
std::size_t size() const override
void resize(std::size_t size) override
Metafunction for generating a list of elements that can be either stored in an external vectror or,...
static constexpr __PXV_POINTER__ INTERNAL_STORAGE
ProxyVector & operator=(const ProxyVector &other)
__PXV_CONST_ITERATOR__ cend()
__PXV_ITERATOR__ begin()
container_type::const_reference const_reference
container_type::pointer storage_pointer
std::size_t size() const
std::vector< value_no_cv_t > container_type
void swap(ProxyVector &other)
__PXV_REFERENCE__ back()
__PXV_POINTER__ data() noexcept
std::conditional< std::is_const< value_t >::value, typenamecontainer_type::const_reference, typenamecontainer_type::reference >::type reference
container_type::const_pointer const_pointer
std::conditional< std::is_const< value_t >::value, typenamecontainer_type::const_pointer, typenamecontainer_type::pointer >::type pointer
__PXV_CONST_ITERATOR__ cbegin()
bool operator==(const ProxyVector &other) const
__PXV_ITERATOR__ end()
__PXV_STORAGE_POINTER__ storedData() noexcept
__PXV_REFERENCE__ at(std::size_t n)
__PXV_REFERENCE__ front()
ProxyVectorIterator< value_t, container_type > iterator
container_type * storedDataContainer(bool forceCreation=false)
void set(__PXV_POINTER__ data, std::size_t size)
ProxyVectorIterator< typename std::add_const< value_no_cv_t >::type, container_type > const_iterator
container_type::const_pointer storage_const_pointer
--- layout: doxygen_footer ---