@@ -44,14 +44,6 @@ namespace internal
4444 , public T_RecordComponentData
4545 {
4646 public:
47- /* *
48- * True if this Record contains a scalar record component.
49- * If so, then that record component is the only component contained,
50- * and the last hierarchical layer is skipped (i.e. only one OPEN_PATH
51- * task for Record and RecordComponent).
52- */
53- bool m_containsScalar = false ;
54-
5547 BaseRecordData ();
5648
5749 BaseRecordData (BaseRecordData const &) = delete ;
@@ -124,6 +116,8 @@ class BaseRecord
124116
125117 mapped_type &operator [](key_type const &key) override ;
126118 mapped_type &operator [](key_type &&key) override ;
119+ mapped_type &at (key_type const &key);
120+ mapped_type const &at (key_type const &key) const ;
127121 size_type erase (key_type const &key) override ;
128122 iterator erase (iterator res) override ;
129123 // ! @todo add also, as soon as added in Container:
@@ -162,7 +156,6 @@ class BaseRecord
162156 void flush (std::string const &, internal::FlushParams const &) final ;
163157 virtual void
164158 flush_impl (std::string const &, internal::FlushParams const &) = 0 ;
165- virtual void read () = 0;
166159
167160 /* *
168161 * @brief Check recursively whether this BaseRecord is dirty.
@@ -214,12 +207,15 @@ BaseRecord<T_elem>::operator[](key_type const &key)
214207 " A scalar component can not be contained at "
215208 " the same time as one or more regular components." );
216209
217- mapped_type &ret = Container<T_elem>::operator [](key);
218210 if (keyScalar)
219211 {
220- get ().m_containsScalar = true ;
221- ret.parent () = this ->parent ();
212+ /*
213+ * This activates the RecordComponent API of this object.
214+ */
215+ T_RecordComponent::get ();
222216 }
217+ mapped_type &ret = keyScalar ? static_cast <mapped_type &>(*this )
218+ : T_Container::operator [](key);
223219 return ret;
224220 }
225221}
@@ -240,16 +236,45 @@ BaseRecord<T_elem>::operator[](key_type &&key)
240236 " A scalar component can not be contained at "
241237 " the same time as one or more regular components." );
242238
243- mapped_type &ret = Container<T_elem>::operator [](std::move (key));
244239 if (keyScalar)
245240 {
246- get ().m_containsScalar = true ;
247- ret.parent () = this ->parent ();
241+ /*
242+ * This activates the RecordComponent API of this object.
243+ */
244+ T_RecordComponent::get ();
248245 }
246+ mapped_type &ret = keyScalar ? static_cast <mapped_type &>(*this )
247+ : T_Container::operator [](std::move (key));
249248 return ret;
250249 }
251250}
252251
252+ template <typename T_elem>
253+ auto BaseRecord<T_elem>::at(key_type const &key) -> mapped_type &
254+ {
255+ return const_cast <mapped_type &>(
256+ static_cast <BaseRecord<T_elem> const *>(this )->at (key));
257+ }
258+
259+ template <typename T_elem>
260+ auto BaseRecord<T_elem>::at(key_type const &key) const -> mapped_type const &
261+ {
262+ bool const keyScalar = (key == RecordComponent::SCALAR);
263+ if (keyScalar)
264+ {
265+ if (!get ().m_datasetDefined )
266+ {
267+ throw std::out_of_range (
268+ " [at()] Requested scalar entry from non-scalar record." );
269+ }
270+ return static_cast <mapped_type const &>(*this );
271+ }
272+ else
273+ {
274+ return T_Container::at (key);
275+ }
276+ }
277+
253278template <typename T_elem>
254279inline typename BaseRecord<T_elem>::size_type
255280BaseRecord<T_elem>::erase(key_type const &key)
@@ -260,22 +285,21 @@ BaseRecord<T_elem>::erase(key_type const &key)
260285 res = Container<T_elem>::erase (key);
261286 else
262287 {
263- mapped_type &rc = this ->find (RecordComponent::SCALAR)->second ;
264- if (rc.written ())
288+ if (this ->written ())
265289 {
266290 Parameter<Operation::DELETE_DATASET> dDelete;
267291 dDelete.name = " ." ;
268- this ->IOHandler ()->enqueue (IOTask (&rc , dDelete));
292+ this ->IOHandler ()->enqueue (IOTask (this , dDelete));
269293 this ->IOHandler ()->flush (internal::defaultFlushParams);
270294 }
271- res = Container<T_elem>:: erase (key) ;
295+ res = this -> datasetDefined () ? 1 : 0 ;
272296 }
273297
274298 if (keyScalar)
275299 {
276300 this ->written () = false ;
277301 this ->writable ().abstractFilePosition .reset ();
278- this ->get ().m_containsScalar = false ;
302+ this ->get ().m_datasetDefined = false ;
279303 }
280304 return res;
281305}
@@ -290,23 +314,11 @@ BaseRecord<T_elem>::erase(iterator res)
290314 ret = Container<T_elem>::erase (res);
291315 else
292316 {
293- mapped_type &rc = this ->find (RecordComponent::SCALAR)->second ;
294- if (rc.written ())
295- {
296- Parameter<Operation::DELETE_DATASET> dDelete;
297- dDelete.name = " ." ;
298- this ->IOHandler ()->enqueue (IOTask (&rc, dDelete));
299- this ->IOHandler ()->flush (internal::defaultFlushParams);
300- }
301- ret = Container<T_elem>::erase (res);
317+ throw std::runtime_error (
318+ " Unreachable! Iterators do not yet cover scalars (they will in a "
319+ " later commit)." );
302320 }
303321
304- if (keyScalar)
305- {
306- this ->written () = false ;
307- this ->writable ().abstractFilePosition .reset ();
308- this ->get ().m_containsScalar = false ;
309- }
310322 return ret;
311323}
312324
@@ -320,7 +332,7 @@ inline std::array<double, 7> BaseRecord<T_elem>::unitDimension() const
320332template <typename T_elem>
321333inline bool BaseRecord<T_elem>::scalar() const
322334{
323- return get (). m_containsScalar ;
335+ return this -> datasetDefined () ;
324336}
325337
326338template <typename T_elem>
@@ -362,7 +374,8 @@ template <typename T_elem>
362374inline void BaseRecord<T_elem>::flush(
363375 std::string const &name, internal::FlushParams const &flushParams)
364376{
365- if (!this ->written () && this ->T_Container ::empty ())
377+ if (!this ->written () && this ->T_Container ::empty () &&
378+ !this ->datasetDefined ())
366379 throw std::runtime_error (
367380 " A Record can not be written without any contained "
368381 " RecordComponents: " +
0 commit comments