23 #include "openPMD/Error.hpp"
24 #include "openPMD/IO/Access.hpp"
25 #include "openPMD/backend/Attributable.hpp"
27 #include <initializer_list>
32 #include <type_traits>
36 #ifndef OPENPMD_protected
37 #define OPENPMD_protected protected:
53 constexpr
static bool is_noop =
true;
64 class EraseStaleEntries;
68 typename T_key = std::string,
69 typename T_container = std::map<T_key, T> >
73 using InternalContainer = T_container;
101 typename T_key = std::string,
102 typename T_container = std::map<T_key, T> >
106 std::is_base_of<Attributable, T>::value,
107 "Type of container element must be derived from Writable");
120 using InternalContainer = T_container;
122 std::shared_ptr<ContainerData> m_containerData;
124 inline void setData(std::shared_ptr<ContainerData> containerData)
126 m_containerData = std::move(containerData);
127 Attributable::setData(m_containerData);
130 inline InternalContainer
const &container()
const
132 return m_containerData->m_container;
135 inline InternalContainer &container()
137 return m_containerData->m_container;
141 using key_type =
typename InternalContainer::key_type;
142 using mapped_type =
typename InternalContainer::mapped_type;
143 using value_type =
typename InternalContainer::value_type;
144 using size_type =
typename InternalContainer::size_type;
145 using difference_type =
typename InternalContainer::difference_type;
146 using allocator_type =
typename InternalContainer::allocator_type;
147 using reference =
typename InternalContainer::reference;
148 using const_reference =
typename InternalContainer::const_reference;
149 using pointer =
typename InternalContainer::pointer;
150 using const_pointer =
typename InternalContainer::const_pointer;
151 using iterator =
typename InternalContainer::iterator;
152 using const_iterator =
typename InternalContainer::const_iterator;
153 using reverse_iterator =
typename InternalContainer::reverse_iterator;
154 using const_reverse_iterator =
155 typename InternalContainer::const_reverse_iterator;
157 iterator begin() noexcept
159 return container().begin();
161 const_iterator begin()
const noexcept
163 return container().begin();
165 const_iterator cbegin()
const noexcept
167 return container().cbegin();
170 iterator end() noexcept
172 return container().end();
174 const_iterator end()
const noexcept
176 return container().end();
178 const_iterator cend()
const noexcept
180 return container().cend();
183 reverse_iterator rbegin() noexcept
185 return container().rbegin();
187 const_reverse_iterator rbegin()
const noexcept
189 return container().rbegin();
191 const_reverse_iterator crbegin()
const noexcept
193 return container().crbegin();
196 reverse_iterator rend() noexcept
198 return container().rend();
200 const_reverse_iterator rend()
const noexcept
202 return container().rend();
204 const_reverse_iterator crend()
const noexcept
206 return container().crend();
209 bool empty()
const noexcept
211 return container().empty();
214 size_type size()
const noexcept
216 return container().size();
228 throw std::runtime_error(
229 "Can not clear a container in a read-only Series.");
234 std::pair<iterator, bool> insert(value_type
const &value)
236 return container().insert(value);
238 std::pair<iterator, bool> insert(value_type &&value)
240 return container().insert(value);
242 iterator insert(const_iterator hint, value_type
const &value)
244 return container().insert(hint, value);
246 iterator insert(const_iterator hint, value_type &&value)
248 return container().insert(hint, value);
250 template <
class InputIt>
251 void insert(InputIt first, InputIt last)
253 container().insert(first, last);
255 void insert(std::initializer_list<value_type> ilist)
257 container().insert(ilist);
260 void swap(Container &other)
262 container().swap(other.m_container);
265 mapped_type &at(key_type
const &key)
267 return container().at(key);
269 mapped_type
const &at(key_type
const &key)
const
271 return container().at(key);
286 auto it = container().find(key);
287 if (it != container().end())
291 if (IOHandler()->m_seriesStatus !=
293 access::readOnly(IOHandler()->m_frontendAccess))
296 throw std::out_of_range(out_of_range_msg(key));
300 t.linkHierarchy(writable());
301 auto &ret = container().insert({key, std::move(t)}).first->second;
302 if constexpr (std::is_same_v<T_key, std::string>)
304 ret.writable().ownKeyWithinParent = key;
308 ret.writable().ownKeyWithinParent = std::to_string(key);
327 auto it = container().find(key);
328 if (it != container().end())
332 if (IOHandler()->m_seriesStatus !=
334 access::readOnly(IOHandler()->m_frontendAccess))
337 throw std::out_of_range(out_of_range_msg(key));
341 t.linkHierarchy(writable());
342 auto &ret = container().insert({key, std::move(t)}).first->second;
343 if constexpr (std::is_same_v<T_key, std::string>)
345 ret.writable().ownKeyWithinParent = std::move(key);
349 ret.writable().ownKeyWithinParent =
350 std::to_string(std::move(key));
358 iterator find(key_type
const &key)
360 return container().find(key);
362 const_iterator find(key_type
const &key)
const
364 return container().find(key);
372 size_type
count(key_type
const &key)
const
374 return container().count(key);
385 return container().find(key) != container().end();
396 size_type
erase(key_type
const &key)
399 throw std::runtime_error(
400 "Can not erase from a container in a read-only Series.");
402 auto res = container().find(key);
403 if (res != container().end() && res->second.written())
408 IOHandler()->
flush(internal::defaultFlushParams);
410 return container().erase(key);
417 throw std::runtime_error(
418 "Can not erase from a container in a read-only Series.");
420 if (res != container().end() && res->second.written())
425 IOHandler()->
flush(internal::defaultFlushParams);
427 return container().erase(res);
432 template <
class... Args>
434 -> decltype(InternalContainer().
emplace(std::forward<Args>(args)...))
436 return container().emplace(std::forward<Args>(args)...);
443 void clear_unchecked()
446 throw std::runtime_error(
447 "Clearing a written container not (yet) implemented.");
453 flush(std::string
const &path, internal::FlushParams
const &flushParams)
457 Parameter<Operation::CREATE_PATH> pCreate;
459 IOHandler()->
enqueue(IOTask(
this, pCreate));
462 flushAttributes(flushParams);
465 Container() : Attributable(NoInit())
467 setData(std::make_shared<ContainerData>());
470 Container(NoInit) : Attributable(NoInit())
486 Container(Container
const &other) : Attributable(NoInit())
488 m_attri = other.m_attri;
489 m_containerData = other.m_containerData;
492 Container(Container &&other) : Attributable(NoInit())
496 m_attri = std::move(other.m_attri);
498 m_containerData = std::move(other.m_containerData);
501 Container &operator=(Container
const &other)
503 m_attri = other.m_attri;
504 m_containerData = other.m_containerData;
508 Container &operator=(Container &&other)
512 m_attri = std::move(other.m_attri);
514 m_containerData = std::move(other.m_containerData);
530 template <
typename Container_t>
533 using BareContainer_t =
534 typename std::remove_reference<Container_t>::type;
535 using key_type =
typename BareContainer_t::key_type;
536 using mapped_type =
typename BareContainer_t::mapped_type;
537 std::set<key_type> m_accessedKeys;
545 Container_t m_originalContainer;
549 : m_originalContainer(container_in)
553 : m_originalContainer(std::move(container_in))
559 template <
typename K>
560 mapped_type &operator[](K &&k)
562 m_accessedKeys.insert(k);
563 return m_originalContainer[std::forward<K>(k)];
566 template <
typename K>
567 mapped_type &at(K &&k)
569 m_accessedKeys.insert(k);
570 return m_originalContainer.at(std::forward<K>(k));
578 template <
typename K>
581 m_accessedKeys.erase(std::forward<K>(k));
586 auto &map = m_originalContainer.container();
588 typename BareContainer_t::InternalContainer::const_iterator;
589 std::vector<iterator_t> deleteMe;
590 deleteMe.reserve(map.size() - m_accessedKeys.size());
591 for (iterator_t it = map.begin(); it != map.end(); ++it)
593 auto lookup = m_accessedKeys.find(it->first);
594 if (lookup == m_accessedKeys.end())
596 deleteMe.push_back(it);
599 for (
auto &it : deleteMe)
std::future< void > flush(internal::FlushParams const &)
Process operations in queue according to FIFO.
Definition: AbstractIOHandler.cpp:28
virtual void enqueue(IOTask const &iotask)
Add provided task to queue according to FIFO.
Definition: AbstractIOHandler.hpp:232
Layer to manage storage of attributes associated with file objects.
Definition: Attributable.hpp:101
Map-like container that enforces openPMD requirements and handles IO.
Definition: Container.hpp:104
mapped_type & operator[](key_type const &key)
Access the value that is mapped to a key equivalent to key, creating it if such key does not exist al...
Definition: Container.hpp:284
void clear()
Remove all objects from the container and (if written) from disk.
Definition: Container.hpp:225
size_type erase(key_type const &key)
Remove a single element from the container and (if written) from disk.
Definition: Container.hpp:396
size_type count(key_type const &key) const
This returns either 1 if the key is found in the container of 0 if not.
Definition: Container.hpp:372
bool contains(key_type const &key) const
Checks if there is an element with a key equivalent to an exiting key in the container.
Definition: Container.hpp:383
iterator erase(iterator res)
Definition: Container.hpp:414
auto emplace(Args &&...args) -> decltype(InternalContainer().emplace(std::forward< Args >(args)...))
Definition: Container.hpp:433
mapped_type & operator[](key_type &&key)
Access the value that is mapped to a key equivalent to key, creating it if such key does not exist al...
Definition: Container.hpp:325
Self-contained description of a single IO operation.
Definition: IOTask.hpp:670
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:127
Definition: ParticlePatches.hpp:32
Definition: ParticleSpecies.hpp:34
Implementation for the root level of the openPMD hierarchy.
Definition: Series.hpp:219
Definition: ReadIterations.hpp:35
Return an error string for read-only access.
Definition: OutOfRangeMsg.hpp:37
Definition: Attributable.hpp:57
Definition: Container.hpp:71
InternalContainer m_container
The wrapped container holding all the actual data, e.g.
Definition: Container.hpp:78
This class wraps a Container and forwards operator[]() and at() to it.
Definition: Container.hpp:532
void forget(K &&k)
Remove key from the list of accessed keys.
Definition: Container.hpp:579
Data members for Series.
Definition: Series.hpp:79
@ Parsing
All objects in the openPMD object model are temporarily mutable to allow inserting newly-parsed data.
Public definitions of openPMD-api.
Definition: Date.cpp:29
@ READ_ONLY
Open Series as read-only, fails if Series is not found.
Definition: IOTask.hpp:273
Container Element Creation Policy.
Definition: Container.hpp:52