@@ -32,8 +32,16 @@ namespace openPMD
3232{
3333namespace internal
3434{
35- template <typename T_elem>
36- class BaseRecordData : public ContainerData <T_elem>
35+ template <
36+ typename T_elem, // = T_RecordComponent
37+ /*
38+ * Technically not necessary, but some old compilers ignore friend
39+ * declarations at this place, so we specify the data class explicitly
40+ */
41+ typename T_RecordComponentData = typename T_elem::Data_t>
42+ class BaseRecordData final
43+ : public ContainerData<T_elem>
44+ , public T_RecordComponentData
3745 {
3846 public:
3947 /* *
@@ -55,17 +63,29 @@ namespace internal
5563} // namespace internal
5664
5765template <typename T_elem>
58- class BaseRecord : public Container <T_elem>
66+ class BaseRecord
67+ : public Container<T_elem>
68+ , public T_elem // T_RecordComponent
5969{
70+ using T_RecordComponent = T_elem;
71+ using T_Container = Container<T_elem>;
72+ using T_Self = BaseRecord<T_elem>;
6073 friend class Iteration ;
6174 friend class ParticleSpecies ;
6275 friend class PatchRecord ;
6376 friend class Record ;
6477 friend class Mesh ;
78+ template <typename , typename >
79+ friend class internal ::BaseRecordData;
6580
66- using Data_t = internal::BaseRecordData<T_elem>;
81+ using Data_t =
82+ internal::BaseRecordData<T_elem, typename T_RecordComponent::Data_t>;
6783 std::shared_ptr<Data_t> m_baseRecordData;
6884
85+ static_assert (
86+ traits::GenerationPolicy<T_RecordComponent>::is_noop,
87+ " Internal error: Scalar components cannot have generation policies." );
88+
6989 inline Data_t const &get () const
7090 {
7191 return *m_baseRecordData;
@@ -82,7 +102,8 @@ class BaseRecord : public Container<T_elem>
82102 inline void setData (std::shared_ptr<Data_t> data)
83103 {
84104 m_baseRecordData = std::move (data);
85- Container<T_elem>::setData (m_baseRecordData);
105+ T_Container::setData (m_baseRecordData);
106+ T_RecordComponent::setData (m_baseRecordData);
86107 }
87108
88109public:
@@ -96,8 +117,8 @@ class BaseRecord : public Container<T_elem>
96117 using const_reference = typename Container<T_elem>::const_reference;
97118 using pointer = typename Container<T_elem>::pointer;
98119 using const_pointer = typename Container<T_elem>::const_pointer;
99- using iterator = typename Container<T_elem> ::iterator;
100- using const_iterator = typename Container<T_elem> ::const_iterator;
120+ using iterator = typename T_Container ::iterator;
121+ using const_iterator = typename T_Container ::const_iterator;
101122
102123 virtual ~BaseRecord () = default ;
103124
@@ -158,8 +179,8 @@ class BaseRecord : public Container<T_elem>
158179
159180namespace internal
160181{
161- template <typename T_elem>
162- BaseRecordData<T_elem>::BaseRecordData()
182+ template <typename T_elem, typename T_RecordComponentData >
183+ BaseRecordData<T_elem, T_RecordComponentData >::BaseRecordData()
163184 {
164185 Attributable impl;
165186 impl.setData ({this , [](auto const *) {}});
@@ -170,7 +191,9 @@ namespace internal
170191} // namespace internal
171192
172193template <typename T_elem>
173- BaseRecord<T_elem>::BaseRecord() : Container<T_elem>(Attributable::NoInit())
194+ BaseRecord<T_elem>::BaseRecord()
195+ : T_Container(Attributable::NoInit())
196+ , T_RecordComponent(Attributable::NoInit())
174197{
175198 setData (std::make_shared<Data_t>());
176199}
@@ -291,7 +314,7 @@ template <typename T_elem>
291314inline std::array<double , 7 > BaseRecord<T_elem>::unitDimension() const
292315{
293316 return this ->getAttribute (" unitDimension" )
294- .template get <std::array<double , 7 > >();
317+ .template get <std::array<double , 7 >>();
295318}
296319
297320template <typename T_elem>
@@ -310,7 +333,7 @@ inline void BaseRecord<T_elem>::readBase()
310333 this ->IOHandler ()->enqueue (IOTask (this , aRead));
311334 this ->IOHandler ()->flush (internal::defaultFlushParams);
312335 if (auto val =
313- Attribute (*aRead.resource ).getOptional <std::array<double , 7 > >();
336+ Attribute (*aRead.resource ).getOptional <std::array<double , 7 >>();
314337 val.has_value ())
315338 this ->setAttribute (" unitDimension" , val.value ());
316339 else
@@ -339,7 +362,7 @@ template <typename T_elem>
339362inline void BaseRecord<T_elem>::flush(
340363 std::string const &name, internal::FlushParams const &flushParams)
341364{
342- if (!this ->written () && this ->empty ())
365+ if (!this ->written () && this ->T_Container :: empty ())
343366 throw std::runtime_error (
344367 " A Record can not be written without any contained "
345368 " RecordComponents: " +
0 commit comments