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{
71
72template<typename PXV_value_t, bool PXV_thread_safe>
73friend class ProxyVector;
74
75friend class ProxyVectorIterator<typename std::add_const<value_t>::type, container_t>;
76
77public:
81 using iterator_category = std::bidirectional_iterator_tag;
82
86 using value_type = value_t;
87
91 using difference_type = std::ptrdiff_t;
92
96 using pointer = __PXI_POINTER_TYPE__;
97
101 using reference = __PXI_REFERENCE_TYPE__;
102
103 // Constructors
105
106 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>
107 ProxyVectorIterator(const ProxyVectorIterator<other_value_t, container_t> &other);
108
109 // General methods
110 void swap(ProxyVectorIterator& other) noexcept;
111
112 // Operators
113 ProxyVectorIterator& operator++();
114 ProxyVectorIterator operator++(int);
115
116 ProxyVectorIterator& operator--();
117 ProxyVectorIterator operator--(int);
118
119 ProxyVectorIterator& operator+=(int increment);
120
121 std::size_t operator-(const ProxyVectorIterator &other);
122
123 __PXI_REFERENCE__ operator*() const;
124 __PXI_POINTER__ operator->() const;
125
126 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>
127 ProxyVectorIterator & operator=(const ProxyVectorIterator<other_value_t, container_t> &other);
128
132 bool operator==(const ProxyVectorIterator &other) const
133 {
134 return (m_position == other.m_position);
135 }
136
140 bool operator!=(const ProxyVectorIterator &other) const
141 {
142 return (m_position != other.m_position);
143 }
144
145private:
149 __PXI_POINTER__ m_position;
150
151 // Constructors
152 explicit ProxyVectorIterator(__PXI_POINTER__ position);
153
154};
155
163template<typename pointer_t, typename const_pointer_t>
165{
166
167public:
168 virtual ~ProxyVectorStorageInterface() = default;
169
170 virtual bool empty() const = 0;
171 virtual std::size_t size() const = 0;
172
173 virtual pointer_t data() = 0;
174 virtual const_pointer_t data() const = 0;
175
176 virtual void resize(std::size_t size) = 0;
177
178};
179
188template<typename value_t, typename pointer_t = value_t *, typename const_pointer_t = const value_t *>
189class ProxyVectorDummyStorage : public ProxyVectorStorageInterface<pointer_t, const_pointer_t>
190{
191
192template<typename PXV_value_t, bool PXV_thread_safe>
193friend class ProxyVector;
194
195public:
196 typedef pointer_t pointer;
197 typedef const_pointer_t const_pointer;
198
199 void swap(ProxyVectorDummyStorage &other) noexcept;
200
201 pointer data() override;
202 const_pointer data() const override;
203
204 bool empty() const override;
205 std::size_t size() const override;
206
207 void resize(std::size_t size) override;
208
209protected:
210 ProxyVectorDummyStorage(std::size_t size = 0);
211
212};
213
223template<typename value_t, typename container_t, bool thread_safe>
224class ProxyVectorStorage : public ProxyVectorStorageInterface<typename container_t::pointer, typename container_t::const_pointer>
225{
226
227template<typename PXV_value_t, bool PXV_thread_safe>
228friend class ProxyVector;
229
230public:
231 typedef container_t container_type;
232
233 typedef typename container_t::pointer pointer;
234 typedef typename container_t::const_pointer const_pointer;
235
236 ~ProxyVectorStorage() override;
237
238 void swap(ProxyVectorStorage &other) noexcept;
239
240 container_t * container(bool forceCreation);
241 const container_t * container(bool forceCreation) const;
242
243 pointer data() override;
244 const_pointer data() const override;
245
246 bool empty() const override;
247 std::size_t size() const override;
248
249 void resize(std::size_t size) override;
250
251protected:
252 ProxyVectorStorage(std::size_t size = 0);
254 ProxyVectorStorage(ProxyVectorStorage &&other) = default;
255
258
259private:
260 static const int MEMORY_POOL_VECTOR_COUNT = 10;
261 static const int MEMORY_POOL_MAX_CAPACITY = 128;
262
263 static std::vector<std::unique_ptr<container_t>> m_containerPool;
264
265 std::unique_ptr<container_t> createContainer(std::size_t size, bool allowEmpty);
266 std::unique_ptr<container_t> createContainer(const std::unique_ptr<container_t> &source, bool allowEmpty);
267 void destroyContainer(std::unique_ptr<container_t> *container);
268
269 std::unique_ptr<container_t> m_container;
270
271};
272
290template<typename value_t, bool thread_safe = false>
292{
293
294private:
295 typedef typename std::remove_cv<value_t>::type value_no_cv_t;
296
297public:
301 typedef std::vector<value_no_cv_t> container_type;
302
306 typedef value_t value_type;
307
312
317
321 typedef
322 typename std::conditional<std::is_const<value_t>::value,
323 typename container_type::const_pointer,
324 typename container_type::pointer>::type
326
330 typedef typename container_type::const_pointer const_pointer;
331
335 typedef typename container_type::pointer storage_pointer;
336
340 typedef typename container_type::const_pointer storage_const_pointer;
341
345 typedef
346 typename std::conditional<std::is_const<value_t>::value,
347 typename container_type::const_reference,
348 typename container_type::reference>::type
350
354 typedef typename container_type::const_reference const_reference;
355
359 static constexpr __PXV_POINTER__ INTERNAL_STORAGE = nullptr;
360
362 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
363 ProxyVector(std::size_t size);
364 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
365 ProxyVector(__PXV_POINTER__ data, std::size_t size);
366 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
367 ProxyVector(std::size_t size, std::size_t capacity);
368 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
369 ProxyVector(__PXV_POINTER__ data, std::size_t size, std::size_t capacity);
370 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
371 ProxyVector(__PXV_POINTER__ data, std::size_t size);
372
375
378
379 void swap(ProxyVector &other);
380
381 bool empty() const;
382 std::size_t size() const;
383
384 bool operator==(const ProxyVector &other) const;
385
386 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
387 void set(__PXV_POINTER__ data, std::size_t size);
388 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
389 void set(__PXV_POINTER__ data, std::size_t size, std::size_t capacity);
390 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
391 void set(__PXV_POINTER__ data, std::size_t size);
392
393 __PXV_STORAGE_POINTER__ storedData() noexcept;
394 __PXV_STORAGE_CONST_POINTER__ storedData() const noexcept;
395
396 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
397 container_type * storedDataContainer(bool forceCreation = false);
398 template<typename U = value_t, typename std::enable_if<std::is_const<U>::value, int>::type = 0>
399 const container_type * storedDataContainer(bool forceCreation = false) const;
400
401 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
402 __PXV_POINTER__ data() noexcept;
403 __PXV_CONST_POINTER__ data() const noexcept;
404
405 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
406 __PXV_REFERENCE__ operator[](std::size_t n);
407 __PXV_CONST_REFERENCE__ operator[](std::size_t n) const;
408
409 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
410 __PXV_REFERENCE__ at(std::size_t n);
411 __PXV_CONST_REFERENCE__ at(std::size_t n) const;
412
413 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
414 __PXV_REFERENCE__ front();
415 __PXV_CONST_REFERENCE__ front() const;
416
417 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
418 __PXV_REFERENCE__ back();
419 __PXV_CONST_REFERENCE__ back() const;
420
421 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
422 __PXV_ITERATOR__ begin();
423 __PXV_CONST_ITERATOR__ begin() const;
424
425 template<typename U = value_t, typename std::enable_if<!std::is_const<U>::value, int>::type = 0>
426 __PXV_ITERATOR__ end();
427 __PXV_CONST_ITERATOR__ end() const;
428
429 __PXV_CONST_ITERATOR__ cbegin();
430 __PXV_CONST_ITERATOR__ cend();
431
432private:
436 typedef
437 typename std::conditional<std::is_const<value_t>::value,
438 ProxyVectorStorage<value_no_cv_t, container_type, thread_safe>,
439 ProxyVectorDummyStorage<value_no_cv_t>>::type
440 storage_t;
441
442 storage_t m_storage;
443
444 std::size_t m_size;
445 __PXV_POINTER__ m_data;
446
447};
448
449// Constant proxy vector
450template<typename value_t, bool thread_safe = false>
451using ConstProxyVector = ProxyVector<const value_t, thread_safe>;
452
453}
454
455// Include the implementation
456#include "proxyVector.tpp"
457
458namespace bitpit{
459
460// Some commonly used ProxyVectors are instantiated explicitly
461extern template class ProxyVector<int, true>;
462extern template class ProxyVector<long, true>;
463extern template class ProxyVector<double, true>;
464
465extern template class ProxyVector<int, false>;
466extern template class ProxyVector<long, false>;
467extern template class ProxyVector<double, false>;
468
469extern template class ProxyVector<const int, true>;
470extern template class ProxyVector<const long, true>;
471extern template class ProxyVector<const double, true>;
472
473extern template class ProxyVector<const int, false>;
474extern template class ProxyVector<const long, false>;
475extern template class ProxyVector<const double, false>;
476
477}
478
479#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
__PXI_REFERENCE_TYPE__ reference
bool operator!=(const ProxyVectorIterator &other) const
std::bidirectional_iterator_tag iterator_category
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)
ProxyVector & operator=(ProxyVector &&other)
container_type::const_reference const_reference
container_type::pointer storage_pointer
ProxyVector(__PXV_POINTER__ data, std::size_t size, std::size_t capacity)
ProxyVector(ProxyVector &&other)
std::vector< value_no_cv_t > container_type
void swap(ProxyVector &other)
std::conditional< std::is_const< value_t >::value, typenamecontainer_type::const_reference, typenamecontainer_type::reference >::type reference
ProxyVector(std::size_t size)
container_type::const_pointer const_pointer
std::conditional< std::is_const< value_t >::value, typenamecontainer_type::const_pointer, typenamecontainer_type::pointer >::type pointer
ProxyVector(std::size_t size, std::size_t capacity)
bool operator==(const ProxyVector &other) const
void set(__PXV_POINTER__ data, std::size_t size, std::size_t capacity)
__PXV_STORAGE_POINTER__ storedData() noexcept
ProxyVectorIterator< value_t, container_type > iterator
container_type * storedDataContainer(bool forceCreation=false)
ProxyVector(__PXV_POINTER__ data, std::size_t size)
void set(__PXV_POINTER__ data, std::size_t size)
ProxyVector(const ProxyVector &other)
ProxyVectorIterator< typename std::add_const< value_no_cv_t >::type, container_type > const_iterator
container_type::const_pointer storage_const_pointer