Changeset 18:a6b018b39e81 in rrlib_rtti_conversion


Ignore:
Timestamp:
03.12.2019 14:30:59 (3 months ago)
Author:
Max Reichardt <max.reichardt@…>
Branch:
17.03
Children:
19:08760a06bc3d, 20:c8365294522d
Phase:
public
Message:

Enables single static cast operation to cast from/to underlying types of underlying types (e.g. angular velocity directly from/to double)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tStaticCastOperation.cpp

    r7 r18  
    7474const tStaticCastOperation::tStaticCast tStaticCastOperation::tInstanceNone::value = { { tConversionOption() }, false }; 
    7575 
     76namespace 
     77{ 
     78 
     79struct tCommonUnderlyingTypeResult 
     80{ 
     81  rrlib::rtti::tType common_underlying_type; 
     82  bool cast_from_source_to_common_type_implicit = false; 
     83  bool cast_from_common_to_destination_type_implicit = false; 
     84  bool cast_from_common_to_destination_type_valid = false; 
     85}; 
     86 
     87tCommonUnderlyingTypeResult GetCommonUnderlyingType(const tType& source_type, const tType& destination_type) 
     88{ 
     89  // Count underlying types 
     90  int underlying_type_count_source = 0; 
     91  tType final_underlying_type_source = source_type; 
     92  while (final_underlying_type_source.GetUnderlyingType() != final_underlying_type_source) 
     93  { 
     94    underlying_type_count_source++; 
     95    final_underlying_type_source = final_underlying_type_source.GetUnderlyingType(); 
     96  } 
     97  int underlying_type_count_destination = 0; 
     98  tType final_underlying_type_destination = destination_type; 
     99  while (final_underlying_type_destination.GetUnderlyingType() != final_underlying_type_destination) 
     100  { 
     101    underlying_type_count_destination++; 
     102    final_underlying_type_destination = final_underlying_type_destination.GetUnderlyingType(); 
     103  } 
     104 
     105  tCommonUnderlyingTypeResult result; 
     106  if (final_underlying_type_destination != final_underlying_type_source) 
     107  { 
     108    return result; 
     109  } 
     110 
     111  // Find common parent 
     112  int remaining_types_source = underlying_type_count_source; 
     113  int remaining_types_destination = underlying_type_count_destination; 
     114  tType current_type_source = source_type; 
     115  tType current_type_destination = destination_type; 
     116  result.cast_from_source_to_common_type_implicit = true; 
     117  result.cast_from_common_to_destination_type_implicit = true; 
     118  result.cast_from_common_to_destination_type_valid = true; 
     119 
     120  while (remaining_types_source || remaining_types_destination) 
     121  { 
     122    if (current_type_source == current_type_destination) 
     123    { 
     124      break; 
     125    } 
     126 
     127    bool process_source = remaining_types_source >= remaining_types_destination; 
     128    bool process_destination = remaining_types_destination >= remaining_types_source; 
     129    if (process_source) 
     130    { 
     131      result.cast_from_source_to_common_type_implicit &= static_cast<bool>(current_type_source.GetTypeTraits() & trait_flags::cIS_CAST_TO_UNDERLYING_TYPE_IMPLICIT); 
     132      current_type_source = current_type_source.GetUnderlyingType(); 
     133      remaining_types_source--; 
     134    } 
     135    if (process_destination) 
     136    { 
     137      result.cast_from_common_to_destination_type_valid &= static_cast<bool>(current_type_destination.GetTypeTraits() & trait_flags::cIS_REINTERPRET_CAST_FROM_UNDERLYING_TYPE_VALID); 
     138      result.cast_from_common_to_destination_type_implicit &= static_cast<bool>(current_type_destination.GetTypeTraits() & trait_flags::cIS_CAST_FROM_UNDERLYING_TYPE_IMPLICIT); 
     139      current_type_destination = current_type_destination.GetUnderlyingType(); 
     140      remaining_types_destination--; 
     141    } 
     142  } 
     143  assert(current_type_source == current_type_destination); 
     144  result.common_underlying_type = current_type_source; 
     145  return result; 
     146} 
     147 
     148} 
    76149 
    77150tStaticCastOperation::tStaticCastOperation() : tRegisteredConversionOperation() 
     
    84157    return tConversionOption(source_type, destination_type, 0); 
    85158  } 
    86   if ((source_type.GetUnderlyingType() == destination_type) || 
    87       (source_type.GetUnderlyingType() == destination_type.GetUnderlyingType() && (destination_type.GetTypeTraits() & trait_flags::cIS_REINTERPRET_CAST_FROM_UNDERLYING_TYPE_VALID))) 
     159  tCommonUnderlyingTypeResult result = GetCommonUnderlyingType(source_type, destination_type); 
     160  if (result.common_underlying_type == destination_type || (result.common_underlying_type == source_type && result.cast_from_common_to_destination_type_valid)) 
    88161  { 
    89162    return tConversionOption(source_type, destination_type, 0); 
     
    113186    return tConversionOption(source_type, destination_type, 0); 
    114187  } 
    115   if ((source_type.GetUnderlyingType() == destination_type && (source_type.GetTypeTraits() & trait_flags::cIS_CAST_TO_UNDERLYING_TYPE_IMPLICIT)) || 
    116       (source_type == destination_type.GetUnderlyingType() && (destination_type.GetTypeTraits() & trait_flags::cIS_CAST_FROM_UNDERLYING_TYPE_IMPLICIT)) || 
    117       (source_type.GetUnderlyingType() == destination_type.GetUnderlyingType() && (source_type.GetTypeTraits() & trait_flags::cIS_CAST_TO_UNDERLYING_TYPE_IMPLICIT) && (destination_type.GetTypeTraits() & trait_flags::cIS_CAST_FROM_UNDERLYING_TYPE_IMPLICIT))) 
     188  tCommonUnderlyingTypeResult result = GetCommonUnderlyingType(source_type, destination_type); 
     189  if ((result.common_underlying_type == destination_type && result.cast_from_source_to_common_type_implicit) || (result.common_underlying_type == source_type && result.cast_from_common_to_destination_type_valid && result.cast_from_common_to_destination_type_implicit)) 
    118190  { 
    119191    return tConversionOption(source_type, destination_type, 0); 
Note: See TracChangeset for help on using the changeset viewer.