23 #include "openPMD/backend/Container.hpp"
24 #include "openPMD/RecordComponent.hpp"
25 #include "openPMD/UnitDimension.hpp"
35 template<
typename T_elem >
59 mapped_type& operator[](key_type
const& key)
override;
60 mapped_type& operator[](key_type&& key)
override;
61 size_type erase(key_type
const& key)
override;
62 iterator erase(iterator res)
override;
94 std::shared_ptr< bool > m_containsScalar;
97 void flush(std::string
const&)
final;
98 virtual void flush_impl(std::string
const&) = 0;
99 virtual void read() = 0;
110 dirtyRecursive()
const;
114 template<
typename T_elem >
117 m_containsScalar{b.m_containsScalar}
120 template<
typename T_elem >
122 Container< T_elem >::operator=( b );
123 m_containsScalar = b.m_containsScalar;
127 template<
typename T_elem >
128 BaseRecord< T_elem >::BaseRecord()
129 : Container< T_elem >(),
130 m_containsScalar{std::make_shared< bool >(
false)}
132 this->setAttribute(
"unitDimension",
133 std::array< double, 7 >{{0., 0., 0., 0., 0., 0., 0.}});
137 template<
typename T_elem >
138 inline typename BaseRecord< T_elem >::mapped_type&
139 BaseRecord< T_elem >::operator[](key_type
const& key)
141 auto it = this->find(key);
142 if( it != this->end() )
146 bool const keyScalar = (key == RecordComponent::SCALAR);
147 if( (keyScalar && !Container< T_elem >::empty() && !scalar()) || (scalar() && !keyScalar) )
148 throw std::runtime_error(
"A scalar component can not be contained at "
149 "the same time as one or more regular components.");
154 *m_containsScalar =
true;
155 ret.parent() = this->parent();
161 template<
typename T_elem >
162 inline typename BaseRecord< T_elem >::mapped_type&
163 BaseRecord< T_elem >::operator[](key_type&& key)
165 auto it = this->find(key);
166 if( it != this->end() )
170 bool const keyScalar = (key == RecordComponent::SCALAR);
171 if( (keyScalar && !Container< T_elem >::empty() && !scalar()) || (scalar() && !keyScalar) )
172 throw std::runtime_error(
"A scalar component can not be contained at "
173 "the same time as one or more regular components.");
178 *m_containsScalar =
true;
179 ret.parent() = this->parent();
185 template<
typename T_elem >
186 inline typename BaseRecord< T_elem >::size_type
187 BaseRecord< T_elem >::erase(key_type
const& key)
189 bool const keyScalar = (key == RecordComponent::SCALAR);
191 if( !keyScalar || (keyScalar && this->at(key).constant()) )
195 mapped_type& rc = this->find(RecordComponent::SCALAR)->second;
198 Parameter< Operation::DELETE_DATASET > dDelete;
200 this->IOHandler()->enqueue(IOTask(&rc, dDelete));
201 this->IOHandler()->flush();
208 this->written() =
false;
209 this->writable().abstractFilePosition.reset();
210 *this->m_containsScalar =
false;
215 template<
typename T_elem >
216 inline typename BaseRecord< T_elem >::iterator
217 BaseRecord< T_elem >::erase(iterator res)
219 bool const keyScalar = (res->first == RecordComponent::SCALAR);
221 if( !keyScalar || (keyScalar && this->at(res->first).constant()) )
225 mapped_type& rc = this->find(RecordComponent::SCALAR)->second;
228 Parameter< Operation::DELETE_DATASET > dDelete;
230 this->IOHandler()->enqueue(IOTask(&rc, dDelete));
231 this->IOHandler()->flush();
238 this->written() =
false;
239 this->writable().abstractFilePosition.reset();
240 *this->m_containsScalar =
false;
245 template<
typename T_elem >
246 inline std::array< double, 7 >
249 return this->getAttribute(
"unitDimension").template get< std::array< double, 7 > >();
252 template<
typename T_elem >
256 return *m_containsScalar;
259 template<
typename T_elem >
266 aRead.name =
"unitDimension";
267 this->IOHandler()->enqueue(
IOTask(
this, aRead));
268 this->IOHandler()->flush();
269 if( *aRead.dtype == DT::ARR_DBL_7 )
270 this->setAttribute(
"unitDimension",
Attribute(*aRead.resource).template get< std::array< double, 7 > >());
271 else if( *aRead.dtype == DT::VEC_DOUBLE )
273 auto vec =
Attribute(*aRead.resource).template get< std::vector< double > >();
274 if( vec.size() == 7 )
276 std::array< double, 7 > arr;
277 std::copy(vec.begin(),
280 this->setAttribute(
"unitDimension", arr);
282 throw std::runtime_error(
"Unexpected Attribute datatype for 'unitDimension'");
285 throw std::runtime_error(
"Unexpected Attribute datatype for 'unitDimension'");
287 aRead.name =
"timeOffset";
288 this->IOHandler()->enqueue(IOTask(
this, aRead));
289 this->IOHandler()->flush();
290 if( *aRead.dtype == DT::FLOAT )
291 this->setAttribute(
"timeOffset", Attribute(*aRead.resource).template get< float >());
292 else if( *aRead.dtype == DT::DOUBLE )
293 this->setAttribute(
"timeOffset", Attribute(*aRead.resource).template get< double >());
295 throw std::runtime_error(
"Unexpected Attribute datatype for 'timeOffset'");
298 template<
typename T_elem >
300 BaseRecord< T_elem >::flush(std::string
const& name)
302 if( !this->written() && this->empty() )
303 throw std::runtime_error(
"A Record can not be written without any contained RecordComponents: " + name);
305 this->flush_impl(name);
310 template<
typename T_elem >
312 BaseRecord< T_elem >::dirtyRecursive()
const
318 for(
auto const & pair : *
this )
320 if( pair.second.dirtyRecursive() )