25#ifndef __BITPIT_CONTAINERS_PIERCED_STORAGE_TPP__
26#define __BITPIT_CONTAINERS_PIERCED_STORAGE_TPP__
33template<
typename id_t>
35 : m_kernel(nullptr), m_kernelType(KERNEL_NONE)
44template<
typename id_t>
57template<
typename id_t>
70template<
typename id_t>
107template<
typename id_t>
127template<
typename id_t>
133 setDynamicKernel(kernel, syncMode);
142template<
typename id_t>
148 switch (kernelType) {
170 other.unsetKernel(
true);
183template<
typename id_t>
191 other.unsetKernel(
true);
205template<
typename id_t>
213 other.unsetKernel(
true);
219template<
typename id_t>
237template<
typename id_t>
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.");
248 m_kernelType = KERNEL_STATIC;
251 _postSetStaticKernel();
259template<
typename id_t>
277template<
typename id_t>
281 setStaticKernel(kernel);
284 m_kernelType = KERNEL_DYNAMIC;
287 m_kernel->registerSlave(
this, syncMode);
290 _postSetDynamicKernel();
296template<
typename id_t>
309template<
typename id_t>
316 _postUnsetKernel(release);
326template<
typename id_t>
337template<
typename id_t>
340 if (m_kernelType == KERNEL_NONE) {
344 if (m_kernelType == KERNEL_DYNAMIC) {
345 if (m_kernel->isSlaveRegistered(
this)) {
346 m_kernel->unregisterSlave(
this);
351 m_kernelType = KERNEL_NONE;
359template<
typename id_t>
370template<
typename id_t>
381template<
typename id_t>
384 if (getKernelType() == KERNEL_NONE || getKernelType() == KERNEL_STATIC) {
405template<
typename id_t>
409 std::swap(other.m_kernel, m_kernel);
410 std::swap(other.m_kernelType, m_kernelType);
416template<
typename value_t,
typename id_t>
427template<
typename value_t,
typename id_t>
439template<
typename value_t,
typename id_t>
444 _postSetStaticKernel();
454template<
typename value_t,
typename id_t>
459 _postSetStaticKernel();
460 _postSetDynamicKernel();
469template<
typename value_t,
typename id_t>
472 m_nFields(other.m_nFields), m_fields(other.m_fields)
475 if (this->getKernel()) {
476 _postSetStaticKernel();
478 KernelType kernelType = this->getKernelType();
479 if (kernelType == this->KERNEL_DYNAMIC) {
480 _postSetDynamicKernel();
495template<
typename value_t,
typename id_t>
498 m_nFields(other.m_nFields), m_fields(other.m_fields)
517template<
typename value_t,
typename id_t>
520 m_nFields(other.m_nFields), m_fields(other.m_fields)
543template<
typename value_t,
typename id_t>
546 m_nFields(std::move(other.m_nFields)), m_fields(std::move(other.m_fields))
553 if (kernelType == this->KERNEL_DYNAMIC) {
579template<
typename value_t,
typename id_t>
582 m_nFields(std::move(other.m_nFields)), m_fields(std::move(other.m_fields))
611template<
typename value_t,
typename id_t>
614 m_nFields(std::move(other.m_nFields)), m_fields(std::move(other.m_fields))
634template<
typename value_t,
typename id_t>
638 temporary.
swap(*
this);
650template<
typename value_t,
typename id_t>
654 temporary.
swap(*
this);
664template<
typename value_t,
typename id_t>
679template<
typename value_t,
typename id_t>
683 rawResize(this->m_kernel->rawSize());
692template<
typename value_t,
typename id_t>
705template<
typename value_t,
typename id_t>
722template<
typename value_t,
typename id_t>
725 return (m_fields.size() / m_nFields);
736template<
typename value_t,
typename id_t>
739 switch (action.type) {
741 case PiercedSyncAction::TYPE_CLEAR:
747 case PiercedSyncAction::TYPE_RESERVE:
749 rawReserve(action.info[PiercedSyncAction::INFO_SIZE]);
753 case PiercedSyncAction::TYPE_RESIZE:
755 rawResize(action.info[PiercedSyncAction::INFO_SIZE]);
759 case PiercedSyncAction::TYPE_SHRINK_TO_FIT:
765 case PiercedSyncAction::TYPE_REORDER:
767 if (action.data && action.data->size() > 0) {
768 rawReorder(*action.data);
770 rawResize(action.info[PiercedSyncAction::INFO_SIZE]);
775 case PiercedSyncAction::TYPE_APPEND:
784 case PiercedSyncAction::TYPE_INSERT:
789 rawEmplace(action.info[PiercedSyncAction::INFO_POS]);
793 case PiercedSyncAction::TYPE_OVERWRITE:
794 case PiercedSyncAction::TYPE_OVERWRITE_MULTIPLE:
799 case PiercedSyncAction::TYPE_MOVE_APPEND:
804 rawPushBack(std::move(rawAt(action.info[PiercedSyncAction::INFO_POS_FIRST])));
805 rawEmreplace(action.info[PiercedSyncAction::INFO_POS_FIRST]);
809 case PiercedSyncAction::TYPE_MOVE_INSERT:
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]);
819 case PiercedSyncAction::TYPE_MOVE_OVERWRITE:
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]);
826 case PiercedSyncAction::TYPE_PIERCE:
827 case PiercedSyncAction::TYPE_PIERCE_MULTIPLE:
834 case PiercedSyncAction::TYPE_SWAP:
836 rawSwap(action.info[PiercedSyncAction::INFO_POS_FIRST], action.info[PiercedSyncAction::INFO_POS_SECOND]);
840 case PiercedSyncAction::TYPE_NOOP:
847 throw std::runtime_error(
"Undefined synchronization action.");
859template<
typename value_t,
typename id_t>
862 m_fields.reserve(m_nFields * n);
874template<
typename value_t,
typename id_t>
877 m_fields.shrink_to_fit();
887template<
typename value_t,
typename id_t>
891 std::vector<value_t>().swap(m_fields);
903template<
typename value_t,
typename id_t>
906 auto itr_begin = m_fields.begin() + pos * m_nFields;
907 auto itr_end = itr_begin + n * m_nFields;
909 m_fields.erase(itr_begin, itr_end);
921template<
typename value_t,
typename id_t>
922template<typename T, typename std::enable_if<!std::is_same<T, bool>::value>::type *>
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]);
940template<
typename value_t,
typename id_t>
941template<typename T, typename std::enable_if<std::is_same<T, bool>::value>::type *>
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) {
955 auto temp = m_fields[firstOffset + k];
956 m_fields[firstOffset + k] = m_fields[secondOffset + k];
957 m_fields[secondOffset + k] = temp;
966template<
typename value_t,
typename id_t>
969 std::size_t storageRawSize = rawSize();
970 assert(permutations.size() == storageRawSize);
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;
983 utils::reorderVector<value_t>(fieldPermutations, m_fields, storageRawSize * m_nFields);
993template<
typename value_t,
typename id_t>
996 m_fields.resize(m_nFields * n, value);
1005template<
typename value_t,
typename id_t>
1009 for (std::size_t k = 0; k < m_nFields; ++k) {
1010 rawInitialize(pos, k, std::forward<Args>(args)...);
1021template<
typename value_t,
typename id_t>
1025 rawAt(pos, k).initialize(std::forward<Args>(args)...);
1035template<
typename value_t,
typename id_t>
1038 m_fields.insert(m_fields.begin() + pos * m_nFields, n * m_nFields, value);
1046template<
typename value_t,
typename id_t>
1049 for (std::size_t k = 0; k < m_nFields; ++k) {
1050 m_fields.push_back(value);
1061template<
typename value_t,
typename id_t>
1062template<typename T, typename std::enable_if<!std::is_same<T, bool>::value>::type *,
typename... Args>
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)...);
1077template<
typename value_t,
typename id_t>
1078template<typename T, typename std::enable_if<std::is_same<T, bool>::value>::type *>
1081 rawInsert(pos, 1, value);
1091template<
typename value_t,
typename id_t>
1092template<typename T, typename std::enable_if<!std::is_same<T, bool>::value>::type *,
typename... Args>
1095 for (std::size_t k = 0; k < m_nFields; ++k) {
1096 m_fields.emplace_back(std::forward<Args>(args)...);
1107template<
typename value_t,
typename id_t>
1108template<typename T, typename std::enable_if<std::is_same<T, bool>::value>::type *>
1122template<
typename value_t,
typename id_t>
1123template<
typename... Args>
1126 for (std::size_t k = 0; k < m_nFields; ++k) {
1127 m_fields[pos * m_nFields + k] = value_t(std::forward<Args>(args)...);
1145template<
typename value_t,
typename id_t>
1152 std::cout <<
"It is only possible to swap storages with the same number of fields." << std::endl;
1158 std::swap(other.m_nFields, m_nFields);
1159 std::swap(other.m_fields, m_fields);
1167template<
typename value_t,
typename id_t>
1170 std::fill(m_fields.begin(), m_fields.end(), value);
1180template<
typename value_t,
typename id_t>
1183 return m_fields.data();
1193template<
typename value_t,
typename id_t>
1196 return m_fields.data();
1206template<
typename value_t,
typename id_t>
1209 std::size_t pos = this->m_kernel->getPos(
id);
1211 return rawData(pos, offset);
1221template<
typename value_t,
typename id_t>
1224 std::size_t pos = this->m_kernel->getPos(
id);
1226 return rawData(pos, offset);
1238template<
typename value_t,
typename id_t>
1241 return (data() + pos * m_nFields + offset);
1253template<
typename value_t,
typename id_t>
1256 return (data() + pos * m_nFields + offset);
1267template<
typename value_t,
typename id_t>
1270 if (this->m_kernel->empty()) {
1271 throw std::out_of_range(
"Vector is empty");
1274 return rawAt(this->m_kernel->front(), k);
1285template<
typename value_t,
typename id_t>
1288 if (this->m_kernel->empty()) {
1289 throw std::out_of_range(
"Vector is empty");
1292 return rawAt(this->m_kernel->front(), k);
1303template<
typename value_t,
typename id_t>
1306 if (this->m_kernel->empty()) {
1307 throw std::out_of_range(
"Vector is empty");
1310 return rawAt(this->m_kernel->back(), k);
1321template<
typename value_t,
typename id_t>
1324 if (this->m_kernel->empty()) {
1325 throw std::out_of_range(
"Vector is empty");
1328 return rawAt(this->m_kernel->back(), k);
1339template<
typename value_t,
typename id_t>
1342 std::size_t pos = this->m_kernel->getPos(
id);
1344 return rawAt(pos, k);
1354template<
typename value_t,
typename id_t>
1357 std::size_t pos = this->m_kernel->getPos(
id);
1359 return rawAt(pos, k);
1368template<
typename value_t,
typename id_t>
1380template<
typename value_t,
typename id_t>
1392template<
typename value_t,
typename id_t>
1395 std::size_t pos = this->m_kernel->getPos(
id);
1397 rawCopy(pos, getFieldCount(), 0, values);
1408template<
typename value_t,
typename id_t>
1411 std::size_t pos = this->m_kernel->getPos(
id);
1413 rawCopy(pos, nFields, offset, values);
1422template<
typename value_t,
typename id_t>
1425 for (std::size_t k = 0; k < m_nFields; ++k) {
1437template<
typename value_t,
typename id_t>
1440 std::size_t pos = this->m_kernel->getPos(
id);
1442 rawSet(pos, k, value);
1451template<
typename value_t,
typename id_t>
1454 std::size_t pos = this->m_kernel->getPos(
id);
1456 rawSet(pos, getFieldCount(), 0, values);
1467template<
typename value_t,
typename id_t>
1470 std::size_t pos = this->m_kernel->getPos(
id);
1472 rawSet(pos, nFields, offset, values);
1484template<
typename value_t,
typename id_t>
1487 return m_fields[pos * m_nFields + k];
1499template<
typename value_t,
typename id_t>
1502 return m_fields[pos * m_nFields + k];
1511template<
typename value_t,
typename id_t>
1514 rawCopy(pos, getFieldCount(), 0, values);
1525template<
typename value_t,
typename id_t>
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];
1540template<
typename value_t,
typename id_t>
1543 for (std::size_t k = 0; k < m_nFields; ++k) {
1544 rawSet(pos, k, value);
1555template<
typename value_t,
typename id_t>
1558 m_fields[pos * m_nFields + k] = value;
1567template<
typename value_t,
typename id_t>
1570 rawSet(pos, getFieldCount(), 0, values);
1581template<
typename value_t,
typename id_t>
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];
1596template<
typename value_t,
typename id_t>
1610template<
typename value_t,
typename id_t>
1624template<
typename value_t,
typename id_t>
1636template<
typename value_t,
typename id_t>
1647template<
typename value_t,
typename id_t>
1650 return rawFind(this->m_kernel->m_begin_pos);
1658template<
typename value_t,
typename id_t>
1661 return rawFind(this->m_kernel->m_end_pos);
1669template<
typename value_t,
typename id_t>
1682template<
typename value_t,
typename id_t>
1693template<
typename value_t,
typename id_t>
1696 return rawFind(this->m_kernel->m_begin_pos);
1705template<
typename value_t,
typename id_t>
1708 return rawFind(this->m_kernel->m_end_pos);
1716template<
typename value_t,
typename id_t>
1719 return m_fields.begin();
1729template<
typename value_t,
typename id_t>
1732 return m_fields.end();
1742template<
typename value_t,
typename id_t>
1755template<
typename value_t,
typename id_t>
1766template<
typename value_t,
typename id_t>
1769 return m_fields.cbegin();
1779template<
typename value_t,
typename id_t>
1782 return m_fields.cend();
1790template<
typename value_t,
typename id_t>
1795 std::size_t nElements;
1797 rawResize(nElements);
1800 for (
typename container_t::reference value : m_fields) {
1801 restoreField(stream, value);
1811template<
typename value_t,
typename id_t>
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)
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)
1843 object.restore(stream);
1851template<
typename value_t,
typename id_t>
1859 for (
typename container_t::const_reference value : m_fields) {
1860 dumpField(stream, value);
1870template<
typename value_t,
typename id_t>
1873 bool bool_value = value;
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
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
1900 object.dump(stream);
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
virtual ~PiercedStorageSyncSlave()
void swap(PiercedStorageSyncSlave< id_t > &other) noexcept
virtual void _postSetDynamicKernel()
virtual void _postUnsetKernel(bool release=true)
void setDynamicKernel(const PiercedKernel< id_t > *kernel, PiercedSyncMaster::SyncMode syncMode)
virtual void _postSetStaticKernel()
void unsetKernel(bool release=true)
PiercedStorageSyncSlave()
KernelType getKernelType() const
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)
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)