openPMD-api
ContainerImpls.hpp
1 /* Copyright 2025 Franz Poeschel
2  *
3  * This file is part of openPMD-api.
4  *
5  * openPMD-api is free software: you can redistribute it and/or modify
6  * it under the terms of of either the GNU General Public License or
7  * the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * openPMD-api is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License and the GNU Lesser General Public License
15  * for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * and the GNU Lesser General Public License along with openPMD-api.
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 #pragma once
22 
23 #include "openPMD/snapshots/ContainerTraits.hpp"
24 #include "openPMD/snapshots/RandomAccessIterator.hpp"
25 #include "openPMD/snapshots/StatefulIterator.hpp"
26 
27 #include <optional>
28 
29 /*
30  * Private header, not included in user code.
31  */
32 
33 namespace openPMD
34 {
36 {
37 private:
38  friend class Series;
39 
40  struct Members
41  {
42  /*
43  * Consider the following user code:
44  * > auto iterations = series.snapshots();
45  * > for (auto & iteration : iterations) { ... }
46  *
47  * Here, only the for loop should actually wait for Iteration data. For
48  * ensuring that Iterations are not waited for too early, the
49  * initialization procedures are stored as a `std::function` in here and
50  * only called upon the right moment. Until then, m_bufferedIterator
51  * stays empty.
52  * Compare the implementation of Series::snapshots(). In there, m_begin
53  * is defined either by make_writing_stateful_iterator or
54  * make_reading_stateful_iterator.
55  * The iterator is resolved upon calling get() below.
56  */
57 
58  // Need to put the deferred function behind a shared_ptr to avoid a
59  // gcc14 compiler bug
60  // warning: '*(std::_Function_base*)((char*)this +
61  // 8).std::_Function_base::_M_manager' may be used uninitialized
62  using Deferred_t = std::shared_ptr<std::function<StatefulIterator *()>>;
63  using Evaluated_t = StatefulIterator *;
64  using BufferedIterator_t = std::variant<Deferred_t, Evaluated_t>;
65  BufferedIterator_t m_bufferedIterator = nullptr;
66  };
67  Members members;
68 
70  std::variant<std::function<StatefulIterator *()>, StatefulIterator *>
71  begin);
72 
73  auto get() -> StatefulIterator *;
74  auto get() const -> StatefulIterator const *;
75 
76  using value_type =
78  static auto stateful_to_opaque(StatefulIterator const &it)
80 
81 public:
82  ~StatefulSnapshotsContainer() override;
83 
86  noexcept(Members(std::declval<Members &&>())));
87 
89  operator=(StatefulSnapshotsContainer const &other);
91  operator=(StatefulSnapshotsContainer &&other) noexcept(noexcept(
92  std::declval<Members>().operator=(std::declval<Members &&>())));
93 
94  using AbstractSnapshotsContainer::currentIteration;
95  auto currentIteration() const -> std::optional<value_type const *> override;
96  auto currentIteration() -> std::optional<value_type *> override;
97 
98  auto begin() -> iterator override;
99  auto end() -> iterator override;
100  auto begin() const -> const_iterator override;
101  auto end() const -> const_iterator override;
102  auto rbegin() -> iterator override;
103  auto rend() -> iterator override;
104  auto rbegin() const -> const_iterator override;
105  auto rend() const -> const_iterator override;
106 
107  auto empty() const -> bool override;
108  auto size() const -> size_t override;
109 
110  auto at(key_type const &key) const -> mapped_type const & override;
111  auto at(key_type const &key) -> mapped_type & override;
112 
113  auto operator[](key_type const &key) -> mapped_type & override;
114 
115  auto clear() -> void override;
116 
117  auto find(key_type const &key) -> iterator override;
118  auto find(key_type const &key) const -> const_iterator override;
119 
120  auto contains(key_type const &key) const -> bool override;
121 
122  auto erase(key_type const &key) -> size_type override;
123  auto erase(iterator) -> iterator override;
124 
125  auto emplace(value_type &&) -> std::pair<iterator, bool> override;
126 
127  auto snapshotWorkflow() const -> SnapshotWorkflow override;
128 };
129 
131 {
132 private:
133  friend class Series;
135  Container_t m_cont;
137 
145 
146 public:
147  ~RandomAccessIteratorContainer() override;
148 
151  RandomAccessIteratorContainer &&other) noexcept;
152 
154  operator=(RandomAccessIteratorContainer const &other);
156  operator=(RandomAccessIteratorContainer &&other) noexcept;
157 
158  using AbstractSnapshotsContainer::currentIteration;
159  auto currentIteration() const -> std::optional<value_type const *> override;
160 
161  auto begin() -> iterator override;
162  auto end() -> iterator override;
163  auto begin() const -> const_iterator override;
164  auto end() const -> const_iterator override;
165  auto rbegin() -> iterator override;
166  auto rend() -> iterator override;
167  auto rbegin() const -> const_iterator override;
168  auto rend() const -> const_iterator override;
169 
170  auto empty() const -> bool override;
171  auto size() const -> size_t override;
172 
173  using AbstractSnapshotsContainer::at;
174  auto at(key_type const &key) const -> mapped_type const & override;
175  auto operator[](key_type const &key) -> mapped_type & override;
176 
177  auto clear() -> void override;
178 
179  auto find(key_type const &key) -> iterator override;
180  auto find(key_type const &key) const -> const_iterator override;
181 
182  auto contains(key_type const &key) const -> bool override;
183 
184  auto erase(key_type const &key) -> size_type override;
185  auto erase(iterator) -> iterator override;
186 
187  auto emplace(value_type &&) -> std::pair<iterator, bool> override;
188 
189  auto snapshotWorkflow() const -> SnapshotWorkflow override;
190 };
191 } // namespace openPMD
Definition: ContainerTraits.hpp:118
Map-like container that enforces openPMD requirements and handles IO.
Definition: Container.hpp:104
Logical compilation of data from one snapshot (e.g.
Definition: Iteration.hpp:146
Counterpart to Snapshots class: Iterator type that can wrap different implementations internally.
Definition: ContainerTraits.hpp:43
Definition: ContainerImpls.hpp:131
Definition: RandomAccessIterator.hpp:49
Implementation for the root level of the openPMD hierarchy.
Definition: Series.hpp:288
Based on the logic of the former class ReadIterations, integrating into itself the logic of former Wr...
Definition: StatefulIterator.hpp:204
Definition: ContainerImpls.hpp:36
Public definitions of openPMD-api.
Definition: Date.cpp:29
SnapshotWorkflow
Enum used as a label for distinguishing the different Snapshots implementations.
Definition: ContainerTraits.hpp:109