@@ -42,7 +42,6 @@ namespace internal
4242 RecordComponent impl{
4343 std::shared_ptr<RecordComponentData>{this , [](auto const *) {}}};
4444 impl.setUnitSI (1 );
45- impl.resetDataset (Dataset (Datatype::CHAR, {1 }));
4645 }
4746} // namespace internal
4847
@@ -71,11 +70,17 @@ RecordComponent &RecordComponent::resetDataset(Dataset d)
7170 auto &rc = get ();
7271 if (written ())
7372 {
73+ if (!rc.m_dataset .has_value ())
74+ {
75+ throw error::Internal (
76+ " Internal control flow error: Written record component must "
77+ " have defined datatype and extent." );
78+ }
7479 if (d.dtype == Datatype::UNDEFINED)
7580 {
76- d.dtype = rc.m_dataset .dtype ;
81+ d.dtype = rc.m_dataset .value (). dtype ;
7782 }
78- else if (d.dtype != rc.m_dataset .dtype )
83+ else if (d.dtype != rc.m_dataset .value (). dtype )
7984 {
8085 throw std::runtime_error (
8186 " Cannot change the datatype of a dataset." );
@@ -99,7 +104,7 @@ RecordComponent &RecordComponent::resetDataset(Dataset d)
99104 rc.m_isEmpty = false ;
100105 if (written ())
101106 {
102- rc.m_dataset .extend (std::move (d.extent ));
107+ rc.m_dataset .value (). extend (std::move (d.extent ));
103108 }
104109 else
105110 {
@@ -112,12 +117,28 @@ RecordComponent &RecordComponent::resetDataset(Dataset d)
112117
113118uint8_t RecordComponent::getDimensionality () const
114119{
115- return get ().m_dataset .rank ;
120+ auto &rc = get ();
121+ if (rc.m_dataset .has_value ())
122+ {
123+ return rc.m_dataset .value ().rank ;
124+ }
125+ else
126+ {
127+ return 1 ;
128+ }
116129}
117130
118131Extent RecordComponent::getExtent () const
119132{
120- return get ().m_dataset .extent ;
133+ auto &rc = get ();
134+ if (rc.m_dataset .has_value ())
135+ {
136+ return rc.m_dataset .value ().extent ;
137+ }
138+ else
139+ {
140+ return {1 };
141+ }
121142}
122143
123144namespace detail
@@ -149,6 +170,12 @@ RecordComponent &RecordComponent::makeEmpty(Dataset d)
149170 auto &rc = get ();
150171 if (written ())
151172 {
173+ if (!rc.m_dataset .has_value ())
174+ {
175+ throw error::Internal (
176+ " Internal control flow error: Written record component must "
177+ " have defined datatype and extent." );
178+ }
152179 if (!constant ())
153180 {
154181 throw std::runtime_error (
@@ -158,30 +185,30 @@ RecordComponent &RecordComponent::makeEmpty(Dataset d)
158185 }
159186 if (d.dtype == Datatype::UNDEFINED)
160187 {
161- d.dtype = rc.m_dataset .dtype ;
188+ d.dtype = rc.m_dataset .value (). dtype ;
162189 }
163- else if (d.dtype != rc.m_dataset .dtype )
190+ else if (d.dtype != rc.m_dataset .value (). dtype )
164191 {
165192 throw std::runtime_error (
166193 " Cannot change the datatype of a dataset." );
167194 }
168- rc.m_dataset .extend (std::move (d.extent ));
195+ rc.m_dataset .value (). extend (std::move (d.extent ));
169196 rc.m_hasBeenExtended = true ;
170197 }
171198 else
172199 {
173200 rc.m_dataset = std::move (d);
174201 }
175202
176- if (rc.m_dataset .extent .size () == 0 )
203+ if (rc.m_dataset .value (). extent .size () == 0 )
177204 throw std::runtime_error (" Dataset extent must be at least 1D." );
178205
179206 rc.m_isEmpty = true ;
180207 dirty () = true ;
181208 if (!written ())
182209 {
183210 switchType<detail::DefaultValue<RecordComponent> >(
184- rc.m_dataset .dtype , *this );
211+ rc.m_dataset .value (). dtype , *this );
185212 }
186213 return *this ;
187214}
@@ -213,11 +240,23 @@ void RecordComponent::flush(
213240 /*
214241 * This catches when a user forgets to use resetDataset.
215242 */
216- if (rc.m_dataset .dtype == Datatype::UNDEFINED )
243+ if (! rc.m_dataset .has_value () )
217244 {
218- throw error::WrongAPIUsage (
219- " [RecordComponent] Must set specific datatype (Use "
220- " resetDataset call)." );
245+ // The check for !written() is technically not needed, just
246+ // defensive programming against internal bugs that go on us.
247+ if (!written () && rc.m_chunks .empty ())
248+ {
249+ // No data written yet, just accessed the object so far without
250+ // doing anything
251+ // Just do nothing and skip this record component.
252+ return ;
253+ }
254+ else
255+ {
256+ throw error::WrongAPIUsage (
257+ " [RecordComponent] Must specify dataset type and extent "
258+ " before flushing (see RecordComponent::resetDataset())." );
259+ }
221260 }
222261 if (!written ())
223262 {
@@ -243,7 +282,7 @@ void RecordComponent::flush(
243282 dCreate.name = name;
244283 dCreate.extent = getExtent ();
245284 dCreate.dtype = getDatatype ();
246- dCreate.options = rc.m_dataset .options ;
285+ dCreate.options = rc.m_dataset .value (). options ;
247286 IOHandler ()->enqueue (IOTask (this , dCreate));
248287 }
249288 }
@@ -262,7 +301,7 @@ void RecordComponent::flush(
262301 else
263302 {
264303 Parameter<Operation::EXTEND_DATASET> pExtend;
265- pExtend.extent = rc.m_dataset .extent ;
304+ pExtend.extent = rc.m_dataset .value (). extent ;
266305 IOHandler ()->enqueue (IOTask (this , std::move (pExtend)));
267306 rc.m_hasBeenExtended = false ;
268307 }
0 commit comments