@@ -201,6 +201,22 @@ bool StructMeta::isDerivedType( const StructMeta * derived, const StructMeta * b
201
201
return b != nullptr ;
202
202
}
203
203
204
+ const StructMeta * StructMeta::commonBase ( const StructMeta * x, const StructMeta * y )
205
+ {
206
+ const StructMeta * m = x;
207
+ while ( m && m != y )
208
+ m = m -> m_base.get ();
209
+
210
+ if ( !m )
211
+ {
212
+ m = y;
213
+ while ( m && m != x )
214
+ m = m -> m_base.get ();
215
+ }
216
+ return m;
217
+
218
+ }
219
+
204
220
void StructMeta::initialize ( Struct * s ) const
205
221
{
206
222
// TODO optimize initialize to use default if availbel instead of constructing
@@ -231,25 +247,29 @@ void StructMeta::copyFrom( const Struct * src, Struct * dest )
231
247
if ( unlikely ( src == dest ) )
232
248
return ;
233
249
234
- if ( dest -> meta () != src -> meta () &&
235
- !StructMeta::isDerivedType ( src -> meta (), dest -> meta () ) )
236
- CSP_THROW ( TypeError, " Attempting to copy from struct type '" << src -> meta () -> name () << " ' to struct type '" << dest -> meta () -> name ()
237
- << " '. copy_from may only be used to copy from same type or derived types" );
250
+ const StructMeta * meta = commonBase ( src -> meta (), dest -> meta () );
251
+ if ( !meta )
252
+ {
253
+ CSP_THROW ( TypeError, " Attempting to copy from struct type '" << src -> meta () -> name () << " ' to struct type '" << dest -> meta () -> name ()
254
+ << " '. copy_from may only be used to copy from struct with a common base type" );
255
+ }
238
256
239
- dest -> meta () -> copyFromImpl ( src, dest, false );
257
+ meta -> copyFromImpl ( src, dest, false );
240
258
}
241
259
242
260
void StructMeta::deepcopyFrom ( const Struct * src, Struct * dest )
243
261
{
244
262
if ( unlikely ( src == dest ) )
245
263
return ;
246
264
247
- if ( dest -> meta () != src -> meta () &&
248
- !StructMeta::isDerivedType ( src -> meta (), dest -> meta () ) )
249
- CSP_THROW ( TypeError, " Attempting to deepcopy from struct type '" << src -> meta () -> name () << " ' to struct type '" << dest -> meta () -> name ()
250
- << " '. deepcopy_from may only be used to copy from same type or derived types" );
251
-
252
- dest -> meta () -> copyFromImpl ( src, dest, true );
265
+ const StructMeta * meta = commonBase ( src -> meta (), dest -> meta () );
266
+ if ( !meta )
267
+ {
268
+ CSP_THROW ( TypeError, " Attempting to deepcopy from struct type '" << src -> meta () -> name () << " ' to struct type '" << dest -> meta () -> name ()
269
+ << " '. deepcopy_from may only be used to copy from struct with a common base type" );
270
+ }
271
+
272
+ meta -> copyFromImpl ( src, dest, true );
253
273
}
254
274
255
275
void StructMeta::copyFromImpl ( const Struct * src, Struct * dest, bool deepcopy ) const
@@ -291,12 +311,15 @@ void StructMeta::updateFrom( const Struct * src, Struct * dest )
291
311
if ( unlikely ( src == dest ) )
292
312
return ;
293
313
294
- if ( dest -> meta () != src -> meta () &&
295
- !StructMeta::isDerivedType ( src -> meta (), dest -> meta () ) )
296
- CSP_THROW ( TypeError, " Attempting to update from struct type '" << src -> meta () -> name () << " ' to struct type '" << dest -> meta () -> name ()
297
- << " '. update_from may only be used to update from same type or derived types" );
314
+ const StructMeta * meta = commonBase ( src -> meta (), dest -> meta () );
315
+
316
+ if ( !meta )
317
+ {
318
+ CSP_THROW ( TypeError, " Attempting to update from struct type '" << src -> meta () -> name () << " ' to struct type '" << dest -> meta () -> name ()
319
+ << " '. update_from may only be used to update from struct with a common base type" );
320
+ }
298
321
299
- dest -> meta () -> updateFromImpl ( src, dest );
322
+ meta -> updateFromImpl ( src, dest );
300
323
}
301
324
302
325
void StructMeta::updateFromImpl ( const Struct * src, Struct * dest ) const
0 commit comments