Changeset 40:3a50f65e594b in rrlib_rtti_conversion


Ignore:
Timestamp:
06.02.2021 21:57:58 (8 months ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Children:
41:9222d0d947d4, 42:7ebf3127fed4
Phase:
public
Rebase:
34343464333666323832643035373764366336353932343234373564376334633237383634656433
Message:

Revises implementation of tCustomOperationData: custom types can now be emplaced into storage (instead of using a semi-clean union of variants with use cases).

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • defined_conversions.cpp

    r38 r40  
    147147const rrlib::rtti::tType cBOOL_VECTOR_TYPE = rrlib::rtti::tDataType<std::vector<bool>>(); 
    148148 
     149struct tComputationTypesOperationData 
     150{ 
     151  tType types[2]; 
     152}; 
     153 
    149154 
    150155class tToStringOperation : public tRegisteredConversionOperation 
     
    377382    auto index_parameter = operation.GetParameterValue(); 
    378383    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0; 
    379     auto result = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]).GetVectorElement(index); 
     384    auto result = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]).GetVectorElement(index); 
    380385    if (!result) 
    381386    { 
     
    389394    auto index_parameter = operation.GetParameterValue(); 
    390395    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0; 
    391     auto intermediate = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]).GetVectorElement(index); 
     396    auto intermediate = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]).GetVectorElement(index); 
    392397    if (!intermediate) 
    393398    { 
     
    399404  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override 
    400405  { 
    401     custom_data.ComputationTypes()[0] = conversion_option.source_type; 
    402     while (!(custom_data.ComputationTypes()[0].IsListType() || custom_data.ComputationTypes()[0].IsArray())) 
    403     { 
    404       custom_data.ComputationTypes()[0] = GetUnderlyingTypeOperationsAreInheritedFrom(custom_data.ComputationTypes()[0]); 
    405       if (!custom_data.ComputationTypes()[0]) 
     406    tComputationTypesOperationData types_data; 
     407    types_data.types[0] = conversion_option.source_type; 
     408    while (!(types_data.types[0].IsListType() || types_data.types[0].IsArray())) 
     409    { 
     410      types_data.types[0] = GetUnderlyingTypeOperationsAreInheritedFrom(types_data.types[0]); 
     411      if (!types_data.types[0]) 
    406412      { 
    407413        throw std::runtime_error("Source type must be list or array"); 
    408414      } 
    409415    } 
     416    custom_data.Emplace(types_data); 
    410417  } 
    411418 
     
    434441  static void FirstConversionFunction(const tTypedConstPointer& source_object_original, const tTypedPointer& destination_object_original, const tCurrentConversionOperation& operation) 
    435442  { 
    436     tTypedConstPointer source_object = tTypedConstPointer(source_object_original.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]); 
     443    tTypedConstPointer source_object = tTypedConstPointer(source_object_original.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]); 
    437444    const tType& source_type = source_object.GetType(); 
    438445    tType destination_type = destination_object_original.GetType(); 
     
    643650  } 
    644651 
    645   static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation) 
     652  __attribute__((__noreturn__)) static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation) 
    646653  { 
    647654    throw std::logic_error("Not supported as single or second operation"); 
     
    650657  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override 
    651658  { 
    652     custom_data.ComputationTypes()[0] = conversion_option.source_type; 
    653     while (!(custom_data.ComputationTypes()[0].IsListType() || custom_data.ComputationTypes()[0].IsArray())) 
    654     { 
    655       custom_data.ComputationTypes()[0] = GetUnderlyingTypeOperationsAreInheritedFrom(custom_data.ComputationTypes()[0]); 
    656       if (!custom_data.ComputationTypes()[0]) 
     659    tComputationTypesOperationData types_data; 
     660    types_data.types[0] = conversion_option.source_type; 
     661    while (!(types_data.types[0].IsListType() || types_data.types[0].IsArray())) 
     662    { 
     663      types_data.types[0] = GetUnderlyingTypeOperationsAreInheritedFrom(types_data.types[0]); 
     664      if (!types_data.types[0]) 
    657665      { 
    658666        throw std::runtime_error("Source type must be list or array"); 
    659667      } 
    660668    } 
     669    custom_data.Emplace(types_data); 
    661670  } 
    662671 
     
    694703  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation) 
    695704  { 
    696     const tType& source_type = operation.GetCustomData().ComputationTypes()[0]; 
     705    const tType& source_type = operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]; 
    697706    const tType source_element_type = source_type.GetElementType(); 
    698707    size_t size = source_type.GetArraySize(); 
     
    722731  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override 
    723732  { 
    724     custom_data.ComputationTypes()[0] = conversion_option.source_type; 
    725     while (!custom_data.ComputationTypes()[0].IsArray()) 
    726     { 
    727       custom_data.ComputationTypes()[0] = GetUnderlyingTypeOperationsAreInheritedFrom(custom_data.ComputationTypes()[0]); 
    728       if (!custom_data.ComputationTypes()[0]) 
     733    tComputationTypesOperationData types_data; 
     734    types_data.types[0] = conversion_option.source_type; 
     735    while (!types_data.types[0].IsArray()) 
     736    { 
     737      types_data.types[0] = GetUnderlyingTypeOperationsAreInheritedFrom(types_data.types[0]); 
     738      if (!types_data.types[0]) 
    729739      { 
    730740        throw std::runtime_error("Source type must be array"); 
    731741      } 
    732742    } 
     743    custom_data.Emplace(types_data); 
    733744  } 
    734745} cARRAY_TO_VECTOR; 
     
    825836  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation) 
    826837  { 
    827     size_t size = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]).GetVectorSize(); 
     838    size_t size = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]).GetVectorSize(); 
    828839    operation.Continue(tTypedConstPointer(&size), destination_object); 
    829840  } 
     
    831842  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation) 
    832843  { 
    833     (*destination_object.Get<size_t>()) = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]).GetVectorSize(); 
     844    (*destination_object.Get<size_t>()) = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]).GetVectorSize(); 
    834845  } 
    835846 
    836847  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override 
    837848  { 
    838     custom_data.ComputationTypes()[0] = conversion_option.source_type; 
    839     while (!custom_data.ComputationTypes()[0].IsListType()) 
    840     { 
    841       custom_data.ComputationTypes()[0] = GetUnderlyingTypeOperationsAreInheritedFrom(custom_data.ComputationTypes()[0]); 
    842       if (!custom_data.ComputationTypes()[0]) 
     849    tComputationTypesOperationData types_data; 
     850    types_data.types[0] = conversion_option.source_type; 
     851    while (!types_data.types[0].IsListType()) 
     852    { 
     853      types_data.types[0] = GetUnderlyingTypeOperationsAreInheritedFrom(types_data.types[0]); 
     854      if (!types_data.types[0]) 
    843855      { 
    844856        throw std::runtime_error("Source type must be list"); 
    845857      } 
    846858    } 
     859    custom_data.Emplace(types_data); 
    847860  } 
    848861} cLIST_SIZE; 
     
    951964  static void FinalConversionFunctionArray(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation) 
    952965  { 
    953     auto& custom_data = operation.GetCustomData(); 
    954     const tType source_type = custom_data.ComputationTypes()[0]; 
    955     const tType destination_type = custom_data.ComputationTypes()[1]; 
     966    auto custom_data = operation.GetCustomData(); 
     967    const tType source_type = custom_data.Get<tComputationTypesOperationData>().types[0]; 
     968    const tType destination_type = custom_data.Get<tComputationTypesOperationData>().types[1]; 
    956969    const tType element_type = source_type.GetElementType(); 
    957970    size_t element_size = element_type.GetSize(); 
     
    978991  { 
    979992    const std::vector<bool>* source = source_object.GetUnchecked<std::vector<bool>>(); 
    980     const tType destination_type = operation.GetCustomData().ComputationTypes()[1]; 
     993    const tType destination_type = operation.GetCustomData().Get<tComputationTypesOperationData>().types[1]; 
    981994    size_t destination_elements = destination_type.GetArraySize(); 
    982995 
     
    9941007  static void FinalConversionFunctionVector(const tTypedConstPointer& source_object_original, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation) 
    9951008  { 
    996     auto& custom_data = operation.GetCustomData(); 
    997     const tType destination_type = custom_data.ComputationTypes()[1]; 
     1009    auto custom_data = operation.GetCustomData(); 
     1010    const tType destination_type = custom_data.Get<tComputationTypesOperationData>().types[1]; 
    9981011    const tType element_type = destination_type.GetElementType(); 
    999     tTypedConstPointer source_object(source_object_original.GetRawDataPointer(), custom_data.ComputationTypes()[0]); 
     1012    tTypedConstPointer source_object(source_object_original.GetRawDataPointer(), custom_data.Get<tComputationTypesOperationData>().types[0]); 
    10001013 
    10011014    size_t copy_elements = std::min(source_object.GetVectorSize(), destination_type.GetArraySize()); 
     
    10631076  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override 
    10641077  { 
    1065     custom_data.ComputationTypes()[0] = GetSupportedType(conversion_option.source_type, true); 
    1066     custom_data.ComputationTypes()[1] = GetSupportedType(conversion_option.destination_type, true); 
     1078    tComputationTypesOperationData types_data; 
     1079    types_data.types[0] = GetSupportedType(conversion_option.source_type, true); 
     1080    types_data.types[1] = GetSupportedType(conversion_option.destination_type, true); 
     1081    custom_data.Emplace(types_data); 
    10671082  } 
    10681083 
  • tCompiledConversionOperation.h

    r22 r40  
    9696 
    9797  tCompiledConversionOperation() : tConversionOperationSequence(), conversion_function_first(nullptr), conversion_function_final(nullptr), fixed_offset_first(0), fixed_offset_final(0), flags(0) 
    98   {} 
     98  { 
     99    memset(custom_operation_data_storage, 0, sizeof(custom_operation_data_storage)); 
     100  } 
    99101 
    100102  /*! 
     
    213215   * (note: if use cases appear that require more or different data, this should be extended) 
    214216   */ 
    215   tCustomOperationData custom_operation_data[2]; 
     217  char* custom_operation_data_storage[2 * tCustomOperationData::cMAX_SIZE]; 
     218 
     219  tCustomOperationData CustomOperationData(size_t index) 
     220  { 
     221    return tCustomOperationData(custom_operation_data_storage + index * tCustomOperationData::cMAX_SIZE); 
     222  } 
     223  tConstCustomOperationData CustomOperationData(size_t index) const 
     224  { 
     225    return tConstCustomOperationData(custom_operation_data_storage + index * tCustomOperationData::cMAX_SIZE); 
     226  } 
    216227}; 
    217228 
     
    240251} 
    241252 
    242 inline const tCustomOperationData& tCurrentConversionOperation::GetCustomData() const 
    243 { 
    244   return compiled_operation.custom_operation_data[operation_index]; 
     253inline tConstCustomOperationData tCurrentConversionOperation::GetCustomData() const 
     254{ 
     255  return compiled_operation.CustomOperationData(operation_index); 
    245256} 
    246257 
  • tConversionOperationSequence.cpp

    r32 r40  
    551551  if ((result.conversion_function_first || result.get_destination_reference_function_first) && conversion1 && conversion1->origin) 
    552552  { 
    553     conversion1->origin->OnCompile(*conversion1, result.custom_operation_data[0]); 
     553    auto custom_operation_data = result.CustomOperationData(0); 
     554    conversion1->origin->OnCompile(*conversion1, custom_operation_data); 
    554555  } 
    555556  if ((result.conversion_function_final || result.get_destination_reference_function_final) && conversion2 && conversion2->origin) 
    556557  { 
    557     conversion2->origin->OnCompile(*conversion2, result.custom_operation_data[1]); 
     558    auto custom_operation_data = result.CustomOperationData(1); 
     559    conversion2->origin->OnCompile(*conversion2, custom_operation_data); 
    558560  } 
    559561 
  • tCurrentConversionOperation.h

    r22 r40  
    101101   * (note: implemented in tCompiledConversionOperation.h to handle cyclic dependency) 
    102102   */ 
    103   inline const tCustomOperationData& GetCustomData() const; 
     103  inline tConstCustomOperationData GetCustomData() const; 
    104104}; 
    105105 
  • tRegisteredConversionOperation.h

    r36 r40  
    9494/*! 
    9595 * Custom operation-specific data (e.g. may be filled during compilation for optimization) 
    96  * (note: if use cases appear that require more or different data, this should be extended) 
    9796 */ 
    9897struct tCustomOperationData 
    9998{ 
    100   typedef void (*tConversionFunction)(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation); 
    101   typedef tType tTypeArray[2]; 
    102   typedef const tType tConstTypeArray[2]; 
    103  
    104   union 
    105   { 
    106     tConversionFunction conversion_function; 
    107     void* raw_pointers[2] = { nullptr, nullptr }; 
    108   }; 
    109  
    110   /*! 
    111    * \return Array of two non-initialized types 
    112    */ 
    113   tTypeArray& ComputationTypes() 
    114   { 
    115     return reinterpret_cast<tTypeArray&>(raw_pointers); 
    116   } 
    117   tConstTypeArray& ComputationTypes() const 
    118   { 
    119     return reinterpret_cast<tConstTypeArray&>(raw_pointers); 
     99  enum { cMAX_SIZE = 2 * sizeof(void*) }; 
     100  void* memory; 
     101 
     102  tCustomOperationData(void* memory) : memory(memory) 
     103  {} 
     104 
     105  /*! 
     106   * Adds custom operation data 
     107   * 
     108   * \param data Data to add (may not exceed  cMAX_SIZE) 
     109   */ 
     110  template <typename T> 
     111  void Emplace(const T& data) 
     112  { 
     113    static_assert(sizeof(T) <= cMAX_SIZE, "sizeof(T) must not exceed cMAX_SIZE"); 
     114    new(memory) T(data); 
     115  } 
     116 
     117  /*! 
     118   * \return Previously attached data of type T 
     119   */ 
     120  template <typename T> 
     121  T& Get() 
     122  { 
     123    static_assert(sizeof(T) <= cMAX_SIZE, "sizeof(T) must not exceed cMAX_SIZE"); 
     124    T* data = static_cast<T*>(memory); 
     125    return *data; 
     126  } 
     127}; 
     128 
     129struct tConstCustomOperationData 
     130{ 
     131  const void* memory; 
     132 
     133  tConstCustomOperationData(const void* memory) : memory(memory) 
     134  {} 
     135 
     136  template <typename T> 
     137  const T& Get() const 
     138  { 
     139    static_assert(sizeof(T) <= tCustomOperationData::cMAX_SIZE, "sizeof(T) must not exceed cMAX_SIZE"); 
     140    const T* data = static_cast<const T*>(memory); 
     141    return *data; 
    120142  } 
    121143}; 
  • tStaticCastOperation.cpp

    r30 r40  
    148148} 
    149149 
     150struct tConvertToEnumOperationData 
     151{ 
     152  typedef void (*tConversionFunction)(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation); 
     153  tConversionFunction conversion_function; 
     154}; 
     155 
    150156template <typename TEnumUnderlyingType> 
    151157void ConvertToEnumFinal(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation) 
     
    154160 
    155161  // Obtain value 
    156   tConversionOption::tConversionFunction function = operation.GetCustomData().conversion_function; 
     162  tConversionOption::tConversionFunction function = operation.GetCustomData().Get<tConvertToEnumOperationData>().conversion_function; 
    157163  TEnumUnderlyingType value = 0; 
    158164  if (function) 
     
    219225    tConversionOption option = static_cast_operation.GetConversionOption(conversion_option.source_type, tDataType<TEnumUnderlyingType>(), nullptr); 
    220226    assert(option.first_conversion_function && option.type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION); 
    221     custom_data.conversion_function = option.final_conversion_function; 
     227    tConvertToEnumOperationData operation_data; 
     228    operation_data.conversion_function = option.final_conversion_function; 
     229    custom_data.Emplace(operation_data); 
    222230  } 
    223231} 
Note: See TracChangeset for help on using the changeset viewer.