Loading...
Searching...
No Matches
proxyVector.tpp
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_TPP__
26#define __BITPIT_PROXY_VECTOR_TPP__
27
28namespace bitpit {
29
33template<typename value_t, typename container_t>
38
47template<typename value_t, typename container_t>
48template<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>
53
60template<typename value_t, typename container_t>
62{
63 std::swap(m_position, other.m_position);
64}
65
69template<typename value_t, typename container_t>
76
80template<typename value_t, typename container_t>
89
93template<typename value_t, typename container_t>
100
104template<typename value_t, typename container_t>
106{
107 ProxyVectorIterator tmp(m_position);
108
109 --(*this);
110
111 return tmp;
112}
113
119template<typename value_t, typename container_t>
121{
122 m_position += increment;
123
124 return *this;
125}
126
132template<typename value_t, typename container_t>
134{
135 return *m_position;
136}
137
143template<typename value_t, typename container_t>
145{
146 return m_position;
147}
148
155template<typename value_t, typename container_t>
156template<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>
163
168template<typename value_t, typename container_t>
170 : m_position(position)
171{
172}
173
180template<typename value_t, typename container_t>
182{
183 return (m_position - other.m_position);
184}
185
191template<typename value_t, typename pointer_t, typename const_pointer_t>
196
202template<typename value_t, typename pointer_t, typename const_pointer_t>
207
213template<typename value_t, typename pointer_t, typename const_pointer_t>
214typename ProxyVectorDummyStorage<value_t, pointer_t, const_pointer_t>::pointer ProxyVectorDummyStorage<value_t, pointer_t, const_pointer_t>::data()
215{
216 return nullptr;
217}
218
224template<typename value_t, typename pointer_t, typename const_pointer_t>
225typename ProxyVectorDummyStorage<value_t, pointer_t, const_pointer_t>::const_pointer ProxyVectorDummyStorage<value_t, pointer_t, const_pointer_t>::data() const
226{
227 return nullptr;
228}
229
235template<typename value_t, typename pointer_t, typename const_pointer_t>
240
246template<typename value_t, typename pointer_t, typename const_pointer_t>
251
257template<typename value_t, typename pointer_t, typename const_pointer_t>
262
266template<typename value_t, typename container_t, bool thread_safe>
267std::vector<std::unique_ptr<container_t>> ProxyVectorStorage<value_t, container_t, thread_safe>::m_containerPool = std::vector<std::unique_ptr<container_t>>();
268
276template<typename value_t, typename container_t, bool thread_safe>
277std::unique_ptr<container_t> ProxyVectorStorage<value_t, container_t, thread_safe>::createContainer(std::size_t size, bool allowEmpty)
278{
279 if (size == 0 && !allowEmpty) {
280 return std::unique_ptr<container_t>(nullptr);
281 }
282
283 if (!thread_safe) {
284 if (!m_containerPool.empty()) {
285 std::unique_ptr<container_t> container = std::move(m_containerPool.back());
286 if (container->size() < size) {
287 container->resize(size);
288 }
289
290 m_containerPool.resize(m_containerPool.size() - 1);
291
292 return container;
293 } else {
294 return std::unique_ptr<container_t>(new container_t(size));
295 }
296 } else {
297 return std::unique_ptr<container_t>(new container_t(size));
298 }
299}
300
309template<typename value_t, typename container_t, bool thread_safe>
310std::unique_ptr<container_t> ProxyVectorStorage<value_t, container_t, thread_safe>::createContainer(const std::unique_ptr<container_t> &source, bool allowEmpty)
311{
312 if (!source || source->empty()) {
313 if (allowEmpty) {
314 return createContainer(0, true);
315 } else {
316 return std::unique_ptr<container_t>(nullptr);
317 }
318 }
319
320 if (!thread_safe) {
321 if (!m_containerPool.empty()) {
322 std::unique_ptr<container_t> container = createContainer(source->size(), false);
323 std::copy_n(source->data(), source->size(), container->data());
324
325 return container;
326 } else {
327 return std::unique_ptr<container_t>(new container_t(*source));
328 }
329 } else {
330 return std::unique_ptr<container_t>(new container_t(*source));
331 }
332}
333
337template<typename value_t, typename container_t, bool thread_safe>
338void ProxyVectorStorage<value_t, container_t, thread_safe>::destroyContainer(std::unique_ptr<container_t> *container)
339{
340 if (!(*container)) {
341 return;
342 }
343
344 if (!thread_safe) {
345 if (m_containerPool.size() < MEMORY_POOL_VECTOR_COUNT) {
346 if ((*container)->size() > MEMORY_POOL_MAX_CAPACITY) {
347 (*container)->resize(MEMORY_POOL_MAX_CAPACITY);
348 }
349
350 m_containerPool.emplace_back(std::move(*container));
351 container->reset();
352 }
353 }
354}
355
361template<typename value_t, typename container_t, bool thread_safe>
363 : m_container(createContainer(size, false))
365}
373template<typename value_t, typename container_t, bool thread_safe>
375 : m_container(createContainer(other.m_container, false))
376{
385template<typename value_t, typename container_t, bool thread_safe>
387{
389 this->swap(temporary);
391 return *this;
392}
393
397template<typename value_t, typename container_t, bool thread_safe>
399{
400 destroyContainer(&m_container);
401}
402
410template<typename value_t, typename container_t, bool thread_safe>
413 if (!m_container && forceCreation) {
414 m_container = createContainer(0, true);
417 return m_container.get();
418}
427template<typename value_t, typename container_t, bool thread_safe>
428const container_t * ProxyVectorStorage<value_t, container_t, thread_safe>::container(bool forceCreation) const
429{
430 if (!m_container && forceCreation) {
431 m_container = createContainer(0, true);
432 }
433
434 return m_container.get();
435}
436
442template<typename value_t, typename container_t, bool thread_safe>
444{
445 m_container.swap(other.m_container);
446}
447
453template<typename value_t, typename container_t, bool thread_safe>
454typename ProxyVectorStorage<value_t, container_t, thread_safe>::pointer ProxyVectorStorage<value_t, container_t, thread_safe>::data()
455{
456 if (empty()) {
457 return nullptr;
458 }
459
460 return m_container->data();
461}
462
468template<typename value_t, typename container_t, bool thread_safe>
469typename ProxyVectorStorage<value_t, container_t, thread_safe>::const_pointer ProxyVectorStorage<value_t, container_t, thread_safe>::data() const
470{
471 if (empty()) {
472 return nullptr;
473 }
474
475 return m_container->data();
476}
477
483template<typename value_t, typename container_t, bool thread_safe>
485{
486 if (!m_container) {
487 return true;
488 }
489
490 return m_container->empty();
491}
492
498template<typename value_t, typename container_t, bool thread_safe>
500{
501 if (!m_container) {
502 return 0;
503 }
504
505 return m_container->size();
506}
507
513template<typename value_t, typename container_t, bool thread_safe>
515{
516 if (size == 0) {
517 destroyContainer(&m_container);
518 return;
519
520 }
521
522 if (m_container) {
523 m_container->resize(size);
524 } else {
525 m_container = createContainer(size, false);
526 }
527}
528
532template<typename value_t, bool thread_safe>
534 : m_size(0), m_data(nullptr)
535{
536}
537
550template<typename value_t, bool thread_safe>
551template<typename other_value_t, typename std::enable_if<std::is_const<other_value_t>::value, int>::type>
553 : ProxyVector<value_t, thread_safe>(INTERNAL_STORAGE, size, size)
554{
555}
556
573template<typename value_t, bool thread_safe>
574template<typename other_value_t, typename std::enable_if<std::is_const<other_value_t>::value, int>::type>
575ProxyVector<value_t, thread_safe>::ProxyVector(std::size_t size, std::size_t capacity)
576 : ProxyVector<value_t, thread_safe>::ProxyVector(INTERNAL_STORAGE, size, capacity)
577{
578}
579
593template<typename value_t, bool thread_safe>
594template<typename other_value_t, typename std::enable_if<std::is_const<other_value_t>::value, int>::type>
595ProxyVector<value_t, thread_safe>::ProxyVector(__PXV_POINTER__ data, std::size_t size)
596 : ProxyVector<value_t, thread_safe>::ProxyVector(data, size, (data != INTERNAL_STORAGE) ? 0 : size)
597{
598}
599
617template<typename value_t, bool thread_safe>
618template<typename other_value_t, typename std::enable_if<std::is_const<other_value_t>::value, int>::type>
619ProxyVector<value_t, thread_safe>::ProxyVector(__PXV_POINTER__ data, std::size_t size, std::size_t capacity)
620 : m_storage(capacity), m_size(size), m_data((data != INTERNAL_STORAGE) ? data : m_storage.data())
621{
622}
623
635template<typename value_t, bool thread_safe>
636template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
637ProxyVector<value_t, thread_safe>::ProxyVector(__PXV_POINTER__ data, std::size_t size)
638 : m_storage(0), m_size(size), m_data(data)
639{
640 assert(data != INTERNAL_STORAGE);
641}
642
648template<typename value_t, bool thread_safe>
650 : m_storage(other.m_storage), m_size(other.m_size), m_data(other.storedData() ? m_storage.data() : other.m_data)
651{
652}
653
665template<typename value_t, bool thread_safe>
667 : m_storage(std::move(other.m_storage)), m_size(std::move(other.m_size)), m_data(std::move(other.m_data))
668{
669}
670
679template<typename value_t, bool thread_safe>
681{
682 if (this != &other) {
683 ProxyVector temporary(other);
684 temporary.swap(*this);
685 }
686
687 return *this;
688}
689
704template<typename value_t, bool thread_safe>
706{
707 if (this != &other) {
708 ProxyVector temporary(std::move(other));
709 temporary.swap(*this);
710 }
711
712 return *this;
713}
714
730template<typename value_t, bool thread_safe>
731template<typename other_value_t, typename std::enable_if<std::is_const<other_value_t>::value, int>::type>
732void ProxyVector<value_t, thread_safe>::set(__PXV_POINTER__ data, std::size_t size)
733{
734 std::size_t capacity;
735 if (data != INTERNAL_STORAGE) {
736 capacity = 0;
737 } else {
738 capacity = size;
739 }
740 set(data, size, capacity);
741}
742
762template<typename value_t, bool thread_safe>
763template<typename other_value_t, typename std::enable_if<std::is_const<other_value_t>::value, int>::type>
764void ProxyVector<value_t, thread_safe>::set(__PXV_POINTER__ data, std::size_t size, std::size_t capacity)
765{
766 m_storage.resize(std::max(size, capacity));
767
768 m_size = size;
769 if (data == INTERNAL_STORAGE) {
770 if (m_size == 0) {
771 m_data = nullptr;
772 } else {
773 m_data = m_storage.data();
774 }
775 } else {
776 m_data = data;
777 }
778}
779
793template<typename value_t, bool thread_safe>
794template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
795void ProxyVector<value_t, thread_safe>::set(__PXV_POINTER__ data, std::size_t size)
796{
797 assert(data != INTERNAL_STORAGE);
798
799 m_storage.resize(0);
800
801 m_size = size;
802 m_data = data;
803}
804
813template<typename value_t, bool thread_safe>
814__PXV_STORAGE_POINTER__ ProxyVector<value_t, thread_safe>::storedData() noexcept
815{
816 __PXV_STORAGE_POINTER__ internalData = m_storage.data();
817 if (!internalData) {
818 return nullptr;
819 } else if (internalData != m_data) {
820 return nullptr;
821 }
822
823 return internalData;
824}
825
834template<typename value_t, bool thread_safe>
835__PXV_STORAGE_CONST_POINTER__ ProxyVector<value_t, thread_safe>::storedData() const noexcept
836{
837 __PXV_STORAGE_CONST_POINTER__ internalData = m_storage.data();
838 if (!internalData) {
839 return nullptr;
840 } else if (internalData != m_data) {
841 return nullptr;
842 }
843
844 return internalData;
845}
846
860template<typename value_t, bool thread_safe>
861template<typename U, typename std::enable_if<std::is_const<U>::value, int>::type>
863{
864 return m_storage.container(forceCreation);
865}
866
880template<typename value_t, bool thread_safe>
881template<typename U, typename std::enable_if<std::is_const<U>::value, int>::type>
883{
884 return m_storage.container(forceCreation);
885}
886
892template<typename value_t, bool thread_safe>
894{
895 std::swap(m_size, other.m_size);
896 std::swap(m_data, other.m_data);
897
898 m_storage.swap(other.m_storage);
899}
900
906template<typename value_t, bool thread_safe>
908{
909 if (m_size != other.m_size) {
910 return false;
911 }
912
913 if (!storedData() && !other.storedData()) {
914 if (m_data != other.m_data) {
915 return false;
916 }
917 }
918
919 for (std::size_t i = 0; i < m_size; ++i) {
920 if (m_data[i] != other.m_data[i]) {
921 return false;
922 }
923 }
924
925 return true;
926}
927
933template<typename value_t, bool thread_safe>
935{
936 return size() == 0;
937}
938
944template<typename value_t, bool thread_safe>
946{
947 return m_size;
948}
949
955template<typename value_t, bool thread_safe>
956template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
958{
959 return m_data;
960}
961
969template<typename value_t, bool thread_safe>
970__PXV_CONST_POINTER__ ProxyVector<value_t, thread_safe>::data() const noexcept
971{
972 return m_data;
973}
974
981template<typename value_t, bool thread_safe>
982template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
983__PXV_REFERENCE__ ProxyVector<value_t, thread_safe>::operator[](std::size_t n)
984{
985 return m_data[n];
986}
987
994template<typename value_t, bool thread_safe>
995__PXV_CONST_REFERENCE__ ProxyVector<value_t, thread_safe>::operator[](std::size_t n) const
996{
997 return m_data[n];
998}
999
1006template<typename value_t, bool thread_safe>
1007template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
1008__PXV_REFERENCE__ ProxyVector<value_t, thread_safe>::at(std::size_t n)
1009{
1010 return m_data[n];
1011}
1012
1019template<typename value_t, bool thread_safe>
1020__PXV_CONST_REFERENCE__ ProxyVector<value_t, thread_safe>::at(std::size_t n) const
1021{
1022 return m_data[n];
1023}
1024
1030template<typename value_t, bool thread_safe>
1031template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
1033{
1034 return m_data[0];
1035}
1036
1042template<typename value_t, bool thread_safe>
1043__PXV_CONST_REFERENCE__ ProxyVector<value_t, thread_safe>::front() const
1044{
1045 return m_data[0];
1046}
1047
1053template<typename value_t, bool thread_safe>
1054template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
1056{
1057 return m_data[m_size - 1];
1058}
1059
1065template<typename value_t, bool thread_safe>
1066__PXV_CONST_REFERENCE__ ProxyVector<value_t, thread_safe>::back() const
1067{
1068 return m_data[m_size - 1];
1069}
1070
1076template<typename value_t, bool thread_safe>
1077template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
1079{
1080 return iterator(m_data);
1081}
1082
1088template<typename value_t, bool thread_safe>
1089__PXV_CONST_ITERATOR__ ProxyVector<value_t, thread_safe>::begin() const
1090{
1091 return const_iterator(m_data);
1092}
1093
1099template<typename value_t, bool thread_safe>
1100template<typename other_value_t, typename std::enable_if<!std::is_const<other_value_t>::value, int>::type>
1102{
1103 return iterator(m_data + m_size);
1104}
1105
1113template<typename value_t, bool thread_safe>
1114__PXV_CONST_ITERATOR__ ProxyVector<value_t, thread_safe>::end() const
1115{
1116 return const_iterator(m_data + m_size);
1117}
1118
1124template<typename value_t, bool thread_safe>
1126{
1127 return const_iterator(m_data);
1128}
1129
1138template<typename value_t, bool thread_safe>
1140{
1141 return const_iterator(m_data + m_size);
1142}
1143
1144}
1145
1146#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.
ProxyVectorIterator & operator+=(int increment)
ProxyVectorIterator & operator++()
ProxyVectorIterator & operator--()
__PXI_REFERENCE__ operator*() const
__PXI_POINTER__ operator->() const
void swap(ProxyVectorIterator &other) noexcept
std::size_t operator-(const ProxyVectorIterator &other)
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()
std::size_t size() const
std::vector< value_no_cv_t > container_type
void swap(ProxyVector &other)
__PXV_REFERENCE__ back()
__PXV_POINTER__ data() noexcept
__PXV_CONST_ITERATOR__ cbegin()
bool operator==(const ProxyVector &other) const
__PXV_REFERENCE__ operator[](std::size_t n)
__PXV_ITERATOR__ end()
__PXV_STORAGE_POINTER__ storedData() noexcept
__PXV_REFERENCE__ at(std::size_t n)
__PXV_REFERENCE__ front()
container_type * storedDataContainer(bool forceCreation=false)
void set(__PXV_POINTER__ data, std::size_t size)
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
--- layout: doxygen_footer ---