Loading...
Searching...
No Matches
piercedStorage.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_CONTAINERS_PIERCED_STORAGE_TPP__
26#define __BITPIT_CONTAINERS_PIERCED_STORAGE_TPP__
27
28namespace bitpit {
29
33template<typename id_t>
35 : m_kernel(nullptr), m_kernelType(KERNEL_NONE)
36{
37}
38
44template<typename id_t>
50
57template<typename id_t>
63
70template<typename id_t>
73{
74 KernelType kernelType = other.getKernelType();
75 switch (kernelType) {
76
77 case KERNEL_STATIC:
78 {
79 setStaticKernel(other.m_kernel);
80 break;
81 }
82
83 case KERNEL_DYNAMIC:
84 {
85 setDynamicKernel(other.m_kernel, other.getSyncMode());
86 break;
87 }
88
89 default:
90 {
91 break;
92 }
93
94 }
95}
96
107template<typename id_t>
127template<typename id_t>
130{
131 BITPIT_UNUSED(other);
132
133 setDynamicKernel(kernel, syncMode);
134}
135
142template<typename id_t>
145{
146 // Set kernel
147 KernelType kernelType = other.getKernelType();
148 switch (kernelType) {
149
150 case KERNEL_STATIC:
151 {
152 setStaticKernel(other.m_kernel);
153 break;
154 }
155
156 case KERNEL_DYNAMIC:
157 {
158 setDynamicKernel(other.m_kernel, other.getSyncMode());
159 break;
160 }
161
162 default:
163 {
164 break;
165 }
166
167 }
168
169 // Unset kernel of other storage slave
170 other.unsetKernel(true);
171}
172
183template<typename id_t>
186{
187 // Set kernel
188 setStaticKernel(kernel);
189
190 // Unset kernel of other storage slave
191 other.unsetKernel(true);
192}
193
205template<typename id_t>
208{
209 // Set kernel
210 setDynamicKernel(kernel, syncMode);
211
212 // Unset kernel of other storage slave
213 other.unsetKernel(true);
214}
215
219template<typename id_t>
224
237template<typename id_t>
239{
240 // Set the kernel
241 if (!kernel) {
242 throw std::runtime_error("Unable to set the kernel. Provided kernel is not valid.");
243 } else if (m_kernelType != KERNEL_NONE) {
244 throw std::runtime_error("Unable to set the kernel. The kernel of the storage is already set.");
245 }
246
247 m_kernel = kernel;
248 m_kernelType = KERNEL_STATIC;
249
250 // Action to be performed after setting the kernel
251 _postSetStaticKernel();
252}
253
259template<typename id_t>
261{
262 // Nothing to do
263}
264
277template<typename id_t>
279{
280 // Set the static kernel
281 setStaticKernel(kernel);
282
283 // Update kernel type
284 m_kernelType = KERNEL_DYNAMIC;
285
286 // Register the storage for dynamic synchronization
287 m_kernel->registerSlave(this, syncMode);
288
289 // Action to be performed after setting the kernel
290 _postSetDynamicKernel();
291}
292
296template<typename id_t>
298{
299 // Nothing to do
300}
301
309template<typename id_t>
311{
312 // Detach the kernel
313 detachKernel();
314
315 // Action to be performed after unsetting the kernel
316 _postUnsetKernel(release);
317}
318
326template<typename id_t>
328{
329 BITPIT_UNUSED(release);
330
331 // Nothing to do
332}
333
337template<typename id_t>
339{
340 if (m_kernelType == KERNEL_NONE) {
341 return;
342 }
343
344 if (m_kernelType == KERNEL_DYNAMIC) {
345 if (m_kernel->isSlaveRegistered(this)) {
346 m_kernel->unregisterSlave(this);
350 m_kernel = nullptr;
351 m_kernelType = KERNEL_NONE;
359template<typename id_t>
361{
362 return m_kernel;
364
370template<typename id_t>
371typename PiercedStorageSyncSlave<id_t>::KernelType PiercedStorageSyncSlave<id_t>::getKernelType() const
373 return m_kernelType;
374}
375
381template<typename id_t>
384 if (getKernelType() == KERNEL_NONE || getKernelType() == KERNEL_STATIC) {
386 } else {
387 return m_kernel->getSlaveSyncMode(this);
390
405template<typename id_t>
407{
409 std::swap(other.m_kernel, m_kernel);
410 std::swap(other.m_kernelType, m_kernelType);
411}
416template<typename value_t, typename id_t>
418 : PiercedStorageSyncSlave<id_t>(), m_nFields(1)
421
427template<typename value_t, typename id_t>
429 : PiercedStorageSyncSlave<id_t>(), m_nFields(nFields)
430{
432
439template<typename value_t, typename id_t>
441 : PiercedStorageSyncSlave<id_t>(kernel), m_nFields(nFields)
442{
443 // Base class constructor cannot call virtual functions
444 _postSetStaticKernel();
445}
454template<typename value_t, typename id_t>
456 : PiercedStorageSyncSlave<id_t>(kernel, syncMode), m_nFields(nFields)
457{
458 // Base class constructor cannot call virtual functions
459 _postSetStaticKernel();
460 _postSetDynamicKernel();
462
469template<typename value_t, typename id_t>
472 m_nFields(other.m_nFields), m_fields(other.m_fields)
474 // Base class constructor cannot call virtual functions
475 if (this->getKernel()) {
476 _postSetStaticKernel();
478 KernelType kernelType = this->getKernelType();
479 if (kernelType == this->KERNEL_DYNAMIC) {
480 _postSetDynamicKernel();
481 }
482 }
483}
484
495template<typename value_t, typename id_t>
497 : PiercedStorageSyncSlave<id_t>(other, kernel),
498 m_nFields(other.m_nFields), m_fields(other.m_fields)
499{
500 // Base class constructor cannot call virtual functions
501 if (this->getKernel()) {
503 }
504}
505
517template<typename value_t, typename id_t>
519 : PiercedStorageSyncSlave<id_t>(other, kernel, syncMode),
520 m_nFields(other.m_nFields), m_fields(other.m_fields)
521{
522 // Base class constructor cannot call virtual functions
523 if (this->getKernel()) {
525
527 }
528}
529
543template<typename value_t, typename id_t>
545 : PiercedStorageSyncSlave<long>(other),
546 m_nFields(std::move(other.m_nFields)), m_fields(std::move(other.m_fields))
547{
548 // Base class constructor cannot call virtual functions
549 if (this->getKernel()) {
551
552 KernelType kernelType = this->getKernelType();
553 if (kernelType == this->KERNEL_DYNAMIC) {
555 }
556 }
557
558 // Explicitly reset the number of fields of the other storage
559 other.m_nFields = 0;
560}
561
579template<typename value_t, typename id_t>
581 : PiercedStorageSyncSlave<long>(other, kernel),
582 m_nFields(std::move(other.m_nFields)), m_fields(std::move(other.m_fields))
583{
584 // Base class constructor cannot call virtual functions
585 if (this->getKernel()) {
587 }
588
589 // Explicitly reset the number of fields of the other storage
590 other.m_nFields = 0;
591}
592
611template<typename value_t, typename id_t>
613 : PiercedStorageSyncSlave<long>(other, kernel, syncMode),
614 m_nFields(std::move(other.m_nFields)), m_fields(std::move(other.m_fields))
615{
616 // Base class constructor cannot call virtual functions
617 if (this->getKernel()) {
619
621 }
622
623 // Explicitly reset the number of fields of the other storage
624 other.m_nFields = 0;
625}
626
634template<typename value_t, typename id_t>
636{
637 PiercedStorage<value_t, id_t> temporary(other, nullptr);
638 temporary.swap(*this);
639
640 return *this;
641}
642
650template<typename value_t, typename id_t>
652{
653 PiercedStorage<value_t, id_t> temporary(std::move(other));
654 temporary.swap(*this);
655
656 return *this;
657}
658
664template<typename value_t, typename id_t>
666{
667 return m_nFields;
668}
669
670
679template<typename value_t, typename id_t>
681{
682 // Resize the storage
683 rawResize(this->m_kernel->rawSize());
684 rawShrinkToFit();
685}
686
692template<typename value_t, typename id_t>
694{
695 // Nothing to do
696}
697
705template<typename value_t, typename id_t>
707{
708 // Clear the storage
709 rawClear(release);
710}
711
722template<typename value_t, typename id_t>
724{
725 return (m_fields.size() / m_nFields);
726}
727
736template<typename value_t, typename id_t>
738{
739 switch (action.type) {
740
741 case PiercedSyncAction::TYPE_CLEAR:
742 {
743 rawClear(true);
744 break;
745 }
746
747 case PiercedSyncAction::TYPE_RESERVE:
748 {
749 rawReserve(action.info[PiercedSyncAction::INFO_SIZE]);
750 break;
751 }
752
753 case PiercedSyncAction::TYPE_RESIZE:
754 {
755 rawResize(action.info[PiercedSyncAction::INFO_SIZE]);
756 break;
757 }
758
759 case PiercedSyncAction::TYPE_SHRINK_TO_FIT:
760 {
761 rawShrinkToFit();
762 break;
763 }
764
765 case PiercedSyncAction::TYPE_REORDER:
766 {
767 if (action.data && action.data->size() > 0) {
768 rawReorder(*action.data);
769 }
770 rawResize(action.info[PiercedSyncAction::INFO_SIZE]);
771 rawShrinkToFit();
772 break;
773 }
774
775 case PiercedSyncAction::TYPE_APPEND:
776 {
777 // Since we may increase the sotrage by an element at the time calling
778 // a reserve will hurt performance badly because this will prevent the
779 // automatic reallocation of the storage.
780 rawEmplaceBack();
781 break;
782 }
783
784 case PiercedSyncAction::TYPE_INSERT:
785 {
786 // Since we may increase the sotrage by an element at the time calling
787 // a reserve will hurt performance badly because this will prevent the
788 // automatic reallocation of the storage.
789 rawEmplace(action.info[PiercedSyncAction::INFO_POS]);
790 break;
791 }
792
793 case PiercedSyncAction::TYPE_OVERWRITE:
794 case PiercedSyncAction::TYPE_OVERWRITE_MULTIPLE:
795 {
796 break;
797 }
798
799 case PiercedSyncAction::TYPE_MOVE_APPEND:
800 {
801 // Since we may increase the sotrage by an element at the time calling
802 // a reserve will hurt performance badly because this will prevent the
803 // automatic reallocation of the storage.
804 rawPushBack(std::move(rawAt(action.info[PiercedSyncAction::INFO_POS_FIRST])));
805 rawEmreplace(action.info[PiercedSyncAction::INFO_POS_FIRST]);
806 break;
807 }
808
809 case PiercedSyncAction::TYPE_MOVE_INSERT:
810 {
811 // Since we may increase the sotrage by an element at the time calling
812 // a reserve will hurt performance badly because this will prevent the
813 // automatic reallocation of the storage.
814 rawInsert(action.info[PiercedSyncAction::INFO_POS_SECOND], 1, std::move(rawAt(action.info[PiercedSyncAction::INFO_POS_FIRST])));
815 rawEmreplace(action.info[PiercedSyncAction::INFO_POS_FIRST]);
816 break;
817 }
818
819 case PiercedSyncAction::TYPE_MOVE_OVERWRITE:
820 {
821 rawSet(action.info[PiercedSyncAction::INFO_POS_SECOND], std::move(rawAt(action.info[PiercedSyncAction::INFO_POS_FIRST])));
822 rawEmreplace(action.info[PiercedSyncAction::INFO_POS_FIRST]);
823 break;
824 }
825
826 case PiercedSyncAction::TYPE_PIERCE:
827 case PiercedSyncAction::TYPE_PIERCE_MULTIPLE:
828 {
829 // Nothing to do. To improve performance the element will not be
830 // cleared.
831 break;
832 }
833
834 case PiercedSyncAction::TYPE_SWAP:
835 {
836 rawSwap(action.info[PiercedSyncAction::INFO_POS_FIRST], action.info[PiercedSyncAction::INFO_POS_SECOND]);
837 break;
838 }
839
840 case PiercedSyncAction::TYPE_NOOP:
841 {
842 break;
843 }
844
845 default:
846 {
847 throw std::runtime_error("Undefined synchronization action.");
848 }
849
850 }
851}
852
859template<typename value_t, typename id_t>
861{
862 m_fields.reserve(m_nFields * n);
863}
864
874template<typename value_t, typename id_t>
876{
877 m_fields.shrink_to_fit();
878}
879
887template<typename value_t, typename id_t>
889{
890 if (release) {
891 std::vector<value_t>().swap(m_fields);
892 } else {
893 m_fields.clear();
894 }
895}
896
903template<typename value_t, typename id_t>
904void PiercedStorage<value_t, id_t>::rawErase(std::size_t pos, std::size_t n)
905{
906 auto itr_begin = m_fields.begin() + pos * m_nFields;
907 auto itr_end = itr_begin + n * m_nFields;
908
909 m_fields.erase(itr_begin, itr_end);
910}
911
921template<typename value_t, typename id_t>
922template<typename T, typename std::enable_if<!std::is_same<T, bool>::value>::type *>
923void PiercedStorage<value_t, id_t>::rawSwap(std::size_t pos_first, std::size_t pos_second)
924{
925 std::size_t firstOffset = pos_first * m_nFields;
926 std::size_t secondOffset = pos_second * m_nFields;
927 for (std::size_t k = 0; k < m_nFields; ++k) {
928 std::swap(m_fields[firstOffset + k], m_fields[secondOffset + k]);
929 }
930}
931
940template<typename value_t, typename id_t>
941template<typename T, typename std::enable_if<std::is_same<T, bool>::value>::type *>
942void PiercedStorage<value_t, id_t>::rawSwap(std::size_t pos_first, std::size_t pos_second)
943{
944 std::size_t firstOffset = pos_first * m_nFields;
945 std::size_t secondOffset = pos_second * m_nFields;
946 for (std::size_t k = 0; k < m_nFields; ++k) {
947 // We cannot use std::swap because it will not work for bool storages
948 //
949 // The [] operator of std::vector<bool> returns a temporary object of a
950 // proxy type called std::vector<bool>::reference, rather than an actual
951 // bool&.
952 //
953 // Although the libstdc++ defines an overload for swapping this type of
954 // proxy objects, this is just an extension to the standard.
955 auto temp = m_fields[firstOffset + k];
956 m_fields[firstOffset + k] = m_fields[secondOffset + k];
957 m_fields[secondOffset + k] = temp;
958 }
959}
960
966template<typename value_t, typename id_t>
967void PiercedStorage<value_t, id_t>::rawReorder(const std::vector<std::size_t> &permutations)
968{
969 std::size_t storageRawSize = rawSize();
970 assert(permutations.size() == storageRawSize);
971
972 // Evaluate the permutation of the fields
973 std::vector<std::size_t> fieldPermutations(storageRawSize * m_nFields);
974 for (std::size_t pos = 0; pos < storageRawSize; ++pos) {
975 std::size_t posOffset = pos * m_nFields;
976 std::size_t permutationOffset = permutations[pos] * m_nFields;
977 for (std::size_t k = 0; k < m_nFields; ++k) {
978 fieldPermutations[posOffset + k] = permutationOffset + k;
979 }
980 }
981
982 // Sort the fields
983 utils::reorderVector<value_t>(fieldPermutations, m_fields, storageRawSize * m_nFields);
984}
985
993template<typename value_t, typename id_t>
994void PiercedStorage<value_t, id_t>::rawResize(std::size_t n, const value_t &value)
995{
996 m_fields.resize(m_nFields * n, value);
997}
998
1005template<typename value_t, typename id_t>
1006template<typename... Args, typename PiercedStorage<value_t>::template EnableIfHasInitialize<Args...> * >
1007void PiercedStorage<value_t, id_t>::rawInitialize(std::size_t pos, Args&&... args)
1008{
1009 for (std::size_t k = 0; k < m_nFields; ++k) {
1010 rawInitialize(pos, k, std::forward<Args>(args)...);
1011 }
1012}
1013
1021template<typename value_t, typename id_t>
1022template<typename... Args, typename PiercedStorage<value_t>::template EnableIfHasInitialize<Args...> * >
1023void PiercedStorage<value_t, id_t>::rawInitialize(std::size_t pos, std::size_t k, Args&&... args)
1024{
1025 rawAt(pos, k).initialize(std::forward<Args>(args)...);
1026}
1027
1035template<typename value_t, typename id_t>
1036void PiercedStorage<value_t, id_t>::rawInsert(std::size_t pos, std::size_t n, const value_t &value)
1037{
1038 m_fields.insert(m_fields.begin() + pos * m_nFields, n * m_nFields, value);
1039}
1040
1046template<typename value_t, typename id_t>
1048{
1049 for (std::size_t k = 0; k < m_nFields; ++k) {
1050 m_fields.push_back(value);
1051 }
1052}
1053
1061template<typename value_t, typename id_t>
1062template<typename T, typename std::enable_if<!std::is_same<T, bool>::value>::type *, typename... Args>
1063void PiercedStorage<value_t, id_t>::rawEmplace(std::size_t pos, Args&&... args)
1064{
1065 for (std::size_t k = 0; k < m_nFields; ++k) {
1066 m_fields.emplace(m_fields.begin() + pos * m_nFields + k, std::forward<Args>(args)...);
1067 }
1068}
1069
1077template<typename value_t, typename id_t>
1078template<typename T, typename std::enable_if<std::is_same<T, bool>::value>::type *>
1079void PiercedStorage<value_t, id_t>::rawEmplace(std::size_t pos, bool value)
1080{
1081 rawInsert(pos, 1, value);
1082}
1083
1091template<typename value_t, typename id_t>
1092template<typename T, typename std::enable_if<!std::is_same<T, bool>::value>::type *, typename... Args>
1094{
1095 for (std::size_t k = 0; k < m_nFields; ++k) {
1096 m_fields.emplace_back(std::forward<Args>(args)...);
1097 }
1098}
1099
1107template<typename value_t, typename id_t>
1108template<typename T, typename std::enable_if<std::is_same<T, bool>::value>::type *>
1110{
1111 rawPushBack(value);
1112}
1113
1122template<typename value_t, typename id_t>
1123template<typename... Args>
1124void PiercedStorage<value_t, id_t>::rawEmreplace(std::size_t pos, Args&&... args)
1125{
1126 for (std::size_t k = 0; k < m_nFields; ++k) {
1127 m_fields[pos * m_nFields + k] = value_t(std::forward<Args>(args)...);
1128 }
1129}
1130
1145template<typename value_t, typename id_t>
1147{
1148 // It is only possible to swap two storages with the same number of field.
1149 // If this condition is not fulfilled we can not continue. However, we
1150 // cannot throw an exception because the function is declared snoexcept.
1151 if (other.getFieldCount() != getFieldCount()) {
1152 std::cout << "It is only possible to swap storages with the same number of fields." << std::endl;
1153 assert(false);
1154 exit(EXIT_FAILURE);
1155 }
1156
1158 std::swap(other.m_nFields, m_nFields);
1159 std::swap(other.m_fields, m_fields);
1160}
1161
1167template<typename value_t, typename id_t>
1168void PiercedStorage<value_t, id_t>::fill(const value_t &value)
1169{
1170 std::fill(m_fields.begin(), m_fields.end(), value);
1171}
1172
1180template<typename value_t, typename id_t>
1181__PS_CONST_POINTER__ PiercedStorage<value_t, id_t>::data() const
1182{
1183 return m_fields.data();
1184}
1185
1193template<typename value_t, typename id_t>
1195{
1196 return m_fields.data();
1197}
1198
1206template<typename value_t, typename id_t>
1207__PS_POINTER__ PiercedStorage<value_t, id_t>::data(id_t id, std::size_t offset)
1208{
1209 std::size_t pos = this->m_kernel->getPos(id);
1210
1211 return rawData(pos, offset);
1212}
1213
1221template<typename value_t, typename id_t>
1222__PS_CONST_POINTER__ PiercedStorage<value_t, id_t>::data(id_t id, std::size_t offset) const
1223{
1224 std::size_t pos = this->m_kernel->getPos(id);
1225
1226 return rawData(pos, offset);
1227}
1228
1238template<typename value_t, typename id_t>
1239__PS_POINTER__ PiercedStorage<value_t, id_t>::rawData(std::size_t pos, std::size_t offset)
1240{
1241 return (data() + pos * m_nFields + offset);
1242}
1243
1253template<typename value_t, typename id_t>
1254__PS_CONST_POINTER__ PiercedStorage<value_t, id_t>::rawData(std::size_t pos, std::size_t offset) const
1255{
1256 return (data() + pos * m_nFields + offset);
1257}
1258
1267template<typename value_t, typename id_t>
1268__PS_REFERENCE__ PiercedStorage<value_t, id_t>::front(std::size_t k)
1269{
1270 if (this->m_kernel->empty()) {
1271 throw std::out_of_range("Vector is empty");
1272 }
1273
1274 return rawAt(this->m_kernel->front(), k);
1275}
1276
1285template<typename value_t, typename id_t>
1286__PS_CONST_REFERENCE__ PiercedStorage<value_t, id_t>::front(std::size_t k) const
1287{
1288 if (this->m_kernel->empty()) {
1289 throw std::out_of_range("Vector is empty");
1290 }
1291
1292 return rawAt(this->m_kernel->front(), k);
1293}
1294
1303template<typename value_t, typename id_t>
1304__PS_REFERENCE__ PiercedStorage<value_t, id_t>::back(std::size_t k)
1305{
1306 if (this->m_kernel->empty()) {
1307 throw std::out_of_range("Vector is empty");
1308 }
1309
1310 return rawAt(this->m_kernel->back(), k);
1311}
1312
1321template<typename value_t, typename id_t>
1322__PS_CONST_REFERENCE__ PiercedStorage<value_t, id_t>::back(std::size_t k) const
1323{
1324 if (this->m_kernel->empty()) {
1325 throw std::out_of_range("Vector is empty");
1326 }
1327
1328 return rawAt(this->m_kernel->back(), k);
1329}
1330
1331
1339template<typename value_t, typename id_t>
1340__PS_REFERENCE__ PiercedStorage<value_t, id_t>::at(id_t id, std::size_t k)
1341{
1342 std::size_t pos = this->m_kernel->getPos(id);
1343
1344 return rawAt(pos, k);
1345}
1346
1354template<typename value_t, typename id_t>
1355__PS_CONST_REFERENCE__ PiercedStorage<value_t, id_t>::at(id_t id, std::size_t k) const
1356{
1357 std::size_t pos = this->m_kernel->getPos(id);
1358
1359 return rawAt(pos, k);
1360}
1361
1368template<typename value_t, typename id_t>
1370{
1371 return at(id, 0);
1372}
1373
1380template<typename value_t, typename id_t>
1381__PS_CONST_REFERENCE__ PiercedStorage<value_t, id_t>::operator[](id_t id) const
1382{
1383 return at(id, 0);
1384}
1385
1392template<typename value_t, typename id_t>
1393void PiercedStorage<value_t, id_t>::copy(id_t id, value_t *values) const
1394{
1395 std::size_t pos = this->m_kernel->getPos(id);
1396
1397 rawCopy(pos, getFieldCount(), 0, values);
1398}
1399
1408template<typename value_t, typename id_t>
1409void PiercedStorage<value_t, id_t>::copy(id_t id, std::size_t nFields, std::size_t offset, value_t *values) const
1410{
1411 std::size_t pos = this->m_kernel->getPos(id);
1412
1413 rawCopy(pos, nFields, offset, values);
1414}
1415
1422template<typename value_t, typename id_t>
1423void PiercedStorage<value_t, id_t>::set(id_t id, const value_t &value)
1424{
1425 for (std::size_t k = 0; k < m_nFields; ++k) {
1426 set(id, k, value);
1427 }
1428}
1429
1437template<typename value_t, typename id_t>
1438void PiercedStorage<value_t, id_t>::set(id_t id, std::size_t k, const value_t &value)
1439{
1440 std::size_t pos = this->m_kernel->getPos(id);
1441
1442 rawSet(pos, k, value);
1443}
1444
1451template<typename value_t, typename id_t>
1452void PiercedStorage<value_t, id_t>::set(id_t id, const value_t *values)
1453{
1454 std::size_t pos = this->m_kernel->getPos(id);
1455
1456 rawSet(pos, getFieldCount(), 0, values);
1457}
1458
1467template<typename value_t, typename id_t>
1468void PiercedStorage<value_t, id_t>::set(id_t id, std::size_t nFields, std::size_t offset, const value_t *values)
1469{
1470 std::size_t pos = this->m_kernel->getPos(id);
1471
1472 rawSet(pos, nFields, offset, values);
1473}
1474
1484template<typename value_t, typename id_t>
1485__PS_REFERENCE__ PiercedStorage<value_t, id_t>::rawAt(std::size_t pos, std::size_t k)
1486{
1487 return m_fields[pos * m_nFields + k];
1488}
1489
1499template<typename value_t, typename id_t>
1500__PS_CONST_REFERENCE__ PiercedStorage<value_t, id_t>::rawAt(std::size_t pos, std::size_t k) const
1501{
1502 return m_fields[pos * m_nFields + k];
1503}
1504
1511template<typename value_t, typename id_t>
1512void PiercedStorage<value_t, id_t>::rawCopy(std::size_t pos, value_t *values) const
1513{
1514 rawCopy(pos, getFieldCount(), 0, values);
1515}
1516
1525template<typename value_t, typename id_t>
1526void PiercedStorage<value_t, id_t>::rawCopy(std::size_t pos, std::size_t nFields, std::size_t offset, value_t *values) const
1527{
1528 nFields = std::max(nFields, getFieldCount() - offset);
1529 for (std::size_t k = offset; k < (offset + nFields); ++k) {
1530 values[k] = m_fields[pos * m_nFields + k];
1531 }
1532}
1533
1540template<typename value_t, typename id_t>
1541void PiercedStorage<value_t, id_t>::rawSet(std::size_t pos, const value_t &value)
1542{
1543 for (std::size_t k = 0; k < m_nFields; ++k) {
1544 rawSet(pos, k, value);
1545 }
1546}
1547
1555template<typename value_t, typename id_t>
1556void PiercedStorage<value_t, id_t>::rawSet(std::size_t pos, std::size_t k, const value_t &value)
1557{
1558 m_fields[pos * m_nFields + k] = value;
1559}
1560
1567template<typename value_t, typename id_t>
1568void PiercedStorage<value_t, id_t>::rawSet(std::size_t pos, const value_t *values)
1569{
1570 rawSet(pos, getFieldCount(), 0, values);
1571}
1572
1581template<typename value_t, typename id_t>
1582void PiercedStorage<value_t, id_t>::rawSet(std::size_t pos, std::size_t nFields, std::size_t offset, const value_t *values)
1583{
1584 nFields = std::max(nFields, getFieldCount() - offset);
1585 for (std::size_t k = offset; k < (offset + nFields); ++k) {
1586 m_fields[pos * m_nFields + k] = values[k];
1587 }
1588}
1589
1596template<typename value_t, typename id_t>
1598{
1599 typename PiercedKernel<id_t>::const_iterator iterator = this->m_kernel->find(id);
1600
1601 return rawFind(iterator.getPos());
1602}
1603
1610template<typename value_t, typename id_t>
1612{
1613 typename PiercedKernel<id_t>::const_iterator iterator = this->m_kernel->find(id);
1614
1615 return rawFind(iterator.getPos());
1616}
1617
1624template<typename value_t, typename id_t>
1626{
1627 return iterator(this, pos);
1628}
1629
1636template<typename value_t, typename id_t>
1638{
1639 return const_iterator(this, pos);
1640}
1641
1647template<typename value_t, typename id_t>
1649{
1650 return rawFind(this->m_kernel->m_begin_pos);
1651}
1652
1658template<typename value_t, typename id_t>
1660{
1661 return rawFind(this->m_kernel->m_end_pos);
1662}
1663
1669template<typename value_t, typename id_t>
1671{
1672 return cbegin();
1673}
1674
1682template<typename value_t, typename id_t>
1684{
1685 return cend();
1686}
1687
1693template<typename value_t, typename id_t>
1695{
1696 return rawFind(this->m_kernel->m_begin_pos);
1697}
1698
1705template<typename value_t, typename id_t>
1707{
1708 return rawFind(this->m_kernel->m_end_pos);
1709}
1710
1716template<typename value_t, typename id_t>
1718{
1719 return m_fields.begin();
1720}
1721
1729template<typename value_t, typename id_t>
1731{
1732 return m_fields.end();
1733}
1734
1742template<typename value_t, typename id_t>
1744{
1745 return rawCbegin();
1746}
1747
1755template<typename value_t, typename id_t>
1757{
1758 return rawCend();
1759}
1760
1766template<typename value_t, typename id_t>
1768{
1769 return m_fields.cbegin();
1770}
1771
1779template<typename value_t, typename id_t>
1781{
1782 return m_fields.cend();
1783}
1784
1790template<typename value_t, typename id_t>
1791template<typename T, typename std::enable_if<std::is_pod<T>::value || PiercedStorage<T, id_t>::has_restore()>::type *>
1793{
1794 // Size
1795 std::size_t nElements;
1796 utils::binary::read(stream, nElements);
1797 rawResize(nElements);
1798
1799 // Fill the storage
1800 for (typename container_t::reference value : m_fields) {
1801 restoreField(stream, value);
1802 }
1803}
1804
1811template<typename value_t, typename id_t>
1812void PiercedStorage<value_t, id_t>::restoreField(std::istream &stream, std::vector<bool>::reference value)
1813{
1814 bool bool_value;
1815 utils::binary::read(stream, bool_value);
1816 value = bool_value;
1817}
1818
1825template<typename value_t, typename id_t>
1826template<typename T, typename std::enable_if<!PiercedStorage<T, id_t>::has_restore()>::type *>
1827void PiercedStorage<value_t, id_t>::restoreField(std::istream &stream, value_t &value)
1828{
1829 utils::binary::read(stream, value);
1830}
1831
1832
1839template<typename value_t, typename id_t>
1840template<typename T, typename std::enable_if<PiercedStorage<T, id_t>::has_restore()>::type *>
1841void PiercedStorage<value_t, id_t>::restoreField(std::istream &stream, value_t &object)
1842{
1843 object.restore(stream);
1844}
1845
1851template<typename value_t, typename id_t>
1852template<typename T, typename std::enable_if<std::is_pod<T>::value || PiercedStorage<T, id_t>::has_dump()>::type *>
1853void PiercedStorage<value_t, id_t>::dump(std::ostream &stream) const
1854{
1855 // Size
1856 utils::binary::write(stream, rawSize());
1857
1858 // Fileds
1859 for (typename container_t::const_reference value : m_fields) {
1860 dumpField(stream, value);
1861 }
1862}
1863
1870template<typename value_t, typename id_t>
1871void PiercedStorage<value_t, id_t>::dumpField(std::ostream &stream, std::vector<bool>::const_reference value) const
1872{
1873 bool bool_value = value;
1874 utils::binary::write(stream, bool_value);
1875}
1876
1883template<typename value_t, typename id_t>
1884template<typename T, typename std::enable_if<!PiercedStorage<T, id_t>::has_dump()>::type *>
1885void PiercedStorage<value_t, id_t>::dumpField(std::ostream &stream, const value_t &value) const
1886{
1887 utils::binary::write(stream, value);
1888}
1889
1896template<typename value_t, typename id_t>
1897template<typename T, typename std::enable_if<PiercedStorage<T, id_t>::has_dump()>::type *>
1898void PiercedStorage<value_t, id_t>::dumpField(std::ostream &stream, const value_t &object) const
1899{
1900 object.dump(stream);
1901}
1902
1903}
1904
1905#endif
Iterator for the class PiercedKernel.
std::size_t getPos() const noexcept
Metafunction for generating a pierced kernel.
Iterator for the class PiercedStorage.
Base class for defining storages that acts like a slave in pierced synchronization.
void setStaticKernel(const PiercedKernel< id_t > *kernel)
const PiercedKernel< id_t > * getKernel() const
PiercedSyncMaster::SyncMode getSyncMode() const
void swap(PiercedStorageSyncSlave< id_t > &other) noexcept
virtual void _postUnsetKernel(bool release=true)
void setDynamicKernel(const PiercedKernel< id_t > *kernel, PiercedSyncMaster::SyncMode syncMode)
void unsetKernel(bool release=true)
Metafunction for generating a pierced storage.
raw_iterator rawBegin() noexcept
raw_iterator rawEnd() noexcept
void restore(std::istream &stream)
std::vector< value_t >::const_iterator raw_const_iterator
const_iterator cend() const noexcept
std::vector< value_t >::iterator raw_iterator
void copy(id_t id, value_t *values) const
void rawClear(bool release)
std::size_t getFieldCount() const
void rawReserve(std::size_t n)
void set(id_t id, const value_t &value)
void rawInitialize(std::size_t pos, Args &&... args)
void swap(PiercedStorage &other) noexcept
__PS_REFERENCE__ at(id_t id, std::size_t k=0)
void commitSyncAction(const PiercedSyncAction &action) override
void rawSwap(std::size_t pos_first, std::size_t pos_second)
void _postSetDynamicKernel() override
std::size_t rawSize() const
__PS_REFERENCE__ rawAt(std::size_t pos, std::size_t offset=0)
iterator end() noexcept
static constexpr bool has_dump()
void rawPushBack(const value_t &value)
iterator rawFind(std::size_t pos) noexcept
void rawEmreplace(std::size_t pos, Args &&... args)
void rawCopy(std::size_t pos, value_t *values) const
void rawErase(std::size_t pos, std::size_t n)
__PS_POINTER__ rawData(std::size_t pos, std::size_t offset=0)
void fill(const value_t &value)
iterator find(const id_t &id) noexcept
static constexpr bool has_restore()
iterator begin() noexcept
void _postSetStaticKernel() override
void _postUnsetKernel(bool release=true) override
raw_const_iterator rawCbegin() const noexcept
void rawEmplaceBack(Args &&... args)
void dump(std::ostream &stream) const
void rawEmplace(std::size_t pos, Args &&... args)
const_iterator cbegin() const noexcept
void rawInsert(std::size_t pos, std::size_t n, const value_t &value)
void rawReorder(const std::vector< std::size_t > &permutations)
PiercedStorage & operator=(const PiercedStorage &other)
__PS_REFERENCE__ front(std::size_t k=0)
raw_const_iterator rawCend() const noexcept
void rawSet(std::size_t pos, const value_t &value)
void rawResize(std::size_t n, const value_t &value=value_t())
__PS_REFERENCE__ back(std::size_t k=0)
__PS_REFERENCE__ operator[](id_t id)
PiercedStorageSyncSlave< long >::KernelType KernelType
Action for pierced synchronization.
PiercedSyncMaster::SyncMode getSlaveSyncMode(const PiercedSyncSlave *slave) const
void swap(PiercedSyncSlave &other) noexcept
void write(std::ostream &stream, const std::vector< bool > &container)
void read(std::istream &stream, std::vector< bool > &container)
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
--- layout: doxygen_footer ---