3333
3434namespace openPMD ::internal
3535{
36+ // 1. Helper functions in anonymous namespace (from header)
3637namespace
3738{
3839 template <typename T>
@@ -61,7 +62,7 @@ namespace
6162 }
6263
6364 // Helper function to set geometry based on string value
64- inline auto setMeshGeometryFromString (Mesh &mesh, std::string val)
65+ auto setMeshGeometryFromString (Mesh &mesh, std::string val)
6566 -> std::optional<error::ReadError>
6667 {
6768 if (" cartesian" == val)
@@ -78,7 +79,7 @@ namespace
7879 }
7980
8081 // Helper function to set data order based on char value
81- inline auto setMeshDataOrderFromChar (Mesh &mesh, char val)
82+ auto setMeshDataOrderFromChar (Mesh &mesh, char val)
8283 -> std::optional<error::ReadError>
8384 {
8485 if (val == ' C' || val == ' F' )
@@ -97,7 +98,7 @@ namespace
9798 }
9899
99100 // Helper function to create default axis labels based on dimensionality
100- inline auto createDefaultAxisLabels (uint64_t dimensionality)
101+ auto createDefaultAxisLabels (uint64_t dimensionality)
101102 -> std::vector<std::string>
102103 {
103104 switch (dimensionality)
@@ -134,8 +135,7 @@ namespace
134135 }
135136
136137 // Helper function to create default vector based on dimensionality
137- inline auto
138- createDefaultVector (uint64_t dimensionality, double defaultValue)
138+ auto createDefaultVector (uint64_t dimensionality, double defaultValue)
139139 -> std::vector<double>
140140 {
141141 if (dimensionality < 100 )
@@ -149,6 +149,45 @@ namespace
149149 }
150150} // namespace
151151
152+ // 2. Template implementations from header
153+ // Template implementations from header
154+ template <typename T, typename RecordType>
155+ PostProcessConvertedAttributeImpl<T, RecordType>::
156+ PostProcessConvertedAttributeImpl (RecordType record_in, handler_t reader_in)
157+ : record(std::move(record_in)), reader(reader_in)
158+ {}
159+
160+ template <typename T, typename RecordType>
161+ auto PostProcessConvertedAttributeImpl<T, RecordType>::operator ()(T val)
162+ -> std::optional<error::ReadError>
163+ {
164+ return (*reader)(record, std::move (val));
165+ }
166+
167+ template <typename T, typename RecordType>
168+ auto makePostProcessConvertedAttribute (
169+ RecordType &&record,
170+ std::optional<error::ReadError> (*handler)(
171+ std::remove_reference_t <RecordType> &, T))
172+ -> std::shared_ptr<PostProcessConvertedAttribute<T>>
173+ {
174+ return std::make_shared<PostProcessConvertedAttributeImpl<
175+ T,
176+ std::remove_reference_t <RecordType>>>(
177+ std::forward<RecordType>(record), handler);
178+ }
179+
180+ template <typename T>
181+ template <typename RecordType>
182+ RequireType<T>::RequireType(
183+ RecordType &&record,
184+ std::optional<error::ReadError> (*handler)(
185+ std::remove_reference_t <RecordType> &, T))
186+ : postProcess(makePostProcessConvertedAttribute(
187+ std::forward<RecordType>(record), handler))
188+ {}
189+
190+ // 3. AttributeReader class implementations
152191AttributeReader::AttributeReader (
153192 std::deque<Datatype> eligibleDatatypes_in,
154193 std::optional<std::shared_ptr<ProcessAttribute>> processAttribute_in)
@@ -185,6 +224,7 @@ auto AttributeReader::operator()(
185224 return attribute_read_result::Success{};
186225}
187226
227+ // 4. ConfigAttribute class implementations
188228ConfigAttribute::ConfigAttribute (
189229 Attributable &child_in, char const *attrName_in)
190230 : child(child_in), attrName(attrName_in)
@@ -337,87 +377,8 @@ void ConfigAttribute::operator()(WriteOrRead wor)
337377 }
338378}
339379
340- template <typename Child>
341- auto ScientificDefaults<Child>::asChild() -> Child &
342- {
343- return *static_cast <Child *>(this );
344- }
345-
346- template <typename Child>
347- auto ScientificDefaults<Child>::asChild() const -> Child const &
348- {
349- return *static_cast <Child const *>(this );
350- }
351-
352- template <typename Child>
353- [[nodiscard]] auto
354- ScientificDefaults<Child>::defaultAttribute(char const *attrName)
355- -> ConfigAttribute
356- {
357- return ConfigAttribute{asChild (), attrName};
358- }
359-
360- template <typename Child>
361- template <typename Parent, bool write>
362- void ScientificDefaults<Child>::addParentDefaults(OpenpmdStandard standard)
363- {
364- // Cannot directly call read_impl as it is private
365- if constexpr (write)
366- {
367- asChild ().ScientificDefaults <Parent>::addDefaults (standard);
368- }
369- else
370- {
371- asChild ().ScientificDefaults <Parent>::readDefaults (standard);
372- }
373- }
374-
375- template <typename Child>
376- void ScientificDefaults<Child>::addDefaultsRecursively(OpenpmdStandard standard)
377- {
378- addDefaults (standard);
379- if constexpr (IsContainer_v<Child>)
380- {
381- using Container_t = AsContainer_t<Child>;
382- using mapped_type = typename Container_t::mapped_type;
383- if constexpr (HasScientificDefaults_v<mapped_type>)
384- {
385- for (auto &[_, right] : asChild ())
386- {
387- (void )_;
388- right.ScientificDefaults <mapped_type>::addDefaultsRecursively (
389- standard);
390- }
391- }
392- }
393- // sic! no else
394-
395- if constexpr (std::is_same_v<Child, Iteration>)
396- {
397- for (auto &[_, right] : asChild ().meshes )
398- {
399- (void )_;
400- right.ScientificDefaults <Mesh>::addDefaultsRecursively (standard);
401- }
402- for (auto &[_, right] : asChild ().particles )
403- {
404- (void )_;
405- right.ScientificDefaults <ParticleSpecies>::addDefaultsRecursively (
406- standard);
407- }
408- }
409- else if constexpr (std::is_same_v<Child, ParticleSpecies>)
410- {
411- for (auto &[_, right] : asChild ().particlePatches )
412- {
413- (void )_;
414- right.ScientificDefaults <PatchRecord>::addDefaultsRecursively (
415- standard);
416- }
417- }
418- }
419-
420- // 2, 0.0976562
380+ // 5. ProcessAttribute implementations (RequireScalar, RequireVector,
381+ // RequireType) 2, 0.0976562
421382auto RequireScalar::operator ()(
422383 Attributable &record, char const *attrName, Attribute const &attr)
423384 -> std::optional<error::ReadError>
@@ -500,6 +461,8 @@ auto RequireType<T>::operator()(
500461 converted_or_error);
501462}
502463
464+ // 6. Helper functions in anonymous namespace (require_scalar, require_vector,
465+ // require_type, etc.)
503466namespace
504467{
505468 std::shared_ptr<ProcessAttribute> require_scalar =
@@ -553,6 +516,87 @@ namespace
553516 }
554517} // namespace
555518
519+ // 7. ScientificDefaults template implementations
520+ template <typename Child>
521+ auto ScientificDefaults<Child>::asChild() -> Child &
522+ {
523+ return *static_cast <Child *>(this );
524+ }
525+
526+ template <typename Child>
527+ auto ScientificDefaults<Child>::asChild() const -> Child const &
528+ {
529+ return *static_cast <Child const *>(this );
530+ }
531+
532+ template <typename Child>
533+ [[nodiscard]] auto
534+ ScientificDefaults<Child>::defaultAttribute(char const *attrName)
535+ -> ConfigAttribute
536+ {
537+ return ConfigAttribute{asChild (), attrName};
538+ }
539+
540+ template <typename Child>
541+ template <typename Parent, bool write>
542+ void ScientificDefaults<Child>::addParentDefaults(OpenpmdStandard standard)
543+ {
544+ // Cannot directly call read_impl as it is private
545+ if constexpr (write)
546+ {
547+ asChild ().ScientificDefaults <Parent>::addDefaults (standard);
548+ }
549+ else
550+ {
551+ asChild ().ScientificDefaults <Parent>::readDefaults (standard);
552+ }
553+ }
554+
555+ template <typename Child>
556+ void ScientificDefaults<Child>::addDefaultsRecursively(OpenpmdStandard standard)
557+ {
558+ addDefaults (standard);
559+ if constexpr (IsContainer_v<Child>)
560+ {
561+ using Container_t = AsContainer_t<Child>;
562+ using mapped_type = typename Container_t::mapped_type;
563+ if constexpr (HasScientificDefaults_v<mapped_type>)
564+ {
565+ for (auto &[_, right] : asChild ())
566+ {
567+ (void )_;
568+ right.ScientificDefaults <mapped_type>::addDefaultsRecursively (
569+ standard);
570+ }
571+ }
572+ }
573+ // sic! no else
574+
575+ if constexpr (std::is_same_v<Child, Iteration>)
576+ {
577+ for (auto &[_, right] : asChild ().meshes )
578+ {
579+ (void )_;
580+ right.ScientificDefaults <Mesh>::addDefaultsRecursively (standard);
581+ }
582+ for (auto &[_, right] : asChild ().particles )
583+ {
584+ (void )_;
585+ right.ScientificDefaults <ParticleSpecies>::addDefaultsRecursively (
586+ standard);
587+ }
588+ }
589+ else if constexpr (std::is_same_v<Child, ParticleSpecies>)
590+ {
591+ for (auto &[_, right] : asChild ().particlePatches )
592+ {
593+ (void )_;
594+ right.ScientificDefaults <PatchRecord>::addDefaultsRecursively (
595+ standard);
596+ }
597+ }
598+ }
599+
556600template <typename Child>
557601template <bool write>
558602void ScientificDefaults<Child>::defaults_impl(OpenpmdStandard standard)
@@ -737,6 +781,7 @@ void ScientificDefaults<Child>::readDefaults(OpenpmdStandard standard)
737781 defaults_impl</* write = */ false >(standard);
738782}
739783
784+ // 8. Template instantiations
740785template class ScientificDefaults <Iteration>;
741786template class ScientificDefaults <Mesh>;
742787template class ScientificDefaults <MeshRecordComponent>;
0 commit comments