Changeset 9:f909044a9f7b in rrlib_rtti_conversion


Ignore:
Timestamp:
22.09.2017 01:26:15 (15 months ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Phase:
public
Tags:
tip
Message:

Adds option to specify type conversions operations that are not usually combined (you could call combinations deprecated) and fixes various bugs found with unit test in finroc_plugins_runtime_construction

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • defined_conversions.cpp

    r8 r9  
    144144{ 
    145145 
     146const unsigned int cSTRING_OPERATION_DEFAULT_FLAGS = 0; 
     147 
    146148class tToStringOperation : public tRegisteredConversionOperation 
    147149{ 
    148150public: 
    149   tToStringOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToString", false), tSupportedTypeFilter::STRING_SERIALIZABLE, tDataType<std::string>(), nullptr, tParameterDefinition("Flags", tDataType<unsigned int>(), true)) 
    150   {} 
     151  tToStringOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToString", false), tSupportedTypeFilter::STRING_SERIALIZABLE, tDataType<std::string>(), nullptr, tParameterDefinition("Flags", &cSTRING_OPERATION_DEFAULT_FLAGS, true)) 
     152  { 
     153  } 
    151154 
    152155  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override 
     
    233236    MainConversionFunction(source_object, *destination_object.Get<std::string>(), operation); 
    234237  } 
    235 }; 
     238} cTO_STRING; 
    236239 
    237240class tStringDeserializationOperation : public tRegisteredConversionOperation 
    238241{ 
    239242public: 
    240   tStringDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("String Deserialization", false), tDataType<std::string>(), tSupportedTypeFilter::STRING_SERIALIZABLE) 
     243  tStringDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("String Deserialization", false), tDataType<std::string>(), tSupportedTypeFilter::STRING_SERIALIZABLE, nullptr, tParameterDefinition(), &cTO_STRING) 
    241244  {} 
    242245 
     
    265268    destination_object.Deserialize(stream); 
    266269  } 
    267 }; 
     270} cSTRING_DESERIALIZATION; 
    268271 
    269272class tBinarySerializationOperation : public tRegisteredConversionOperation 
     
    296299    destination_object.Serialize(stream); 
    297300  } 
    298 }; 
     301} cBINARY_SERIALIZATION; 
    299302 
    300303class tBinaryDeserializationOperation : public tRegisteredConversionOperation 
    301304{ 
    302305public: 
    303   tBinaryDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Deserialization", false), tDataType<serialization::tMemoryBuffer>(), tSupportedTypeFilter::STRING_SERIALIZABLE) 
     306  tBinaryDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Deserialization", false), tDataType<serialization::tMemoryBuffer>(), tSupportedTypeFilter::BINARY_SERIALIZABLE, nullptr, tParameterDefinition(), &cBINARY_SERIALIZATION) 
    304307  {} 
    305308 
     
    328331    destination_object.Deserialize(stream); 
    329332  } 
    330 }; 
     333} cBINARY_DESERIALIZATION; 
    331334 
    332335class tGetListElement : public tRegisteredConversionOperation 
     
    342345      return tConversionOption(source_type, destination_type, &FirstConversionFunction, &GetDestinationReference); 
    343346    } 
    344     unsigned int index = parameter ? parameter->GetData<unsigned int>() : 0; 
     347    unsigned int index = 0; 
     348    if (parameter && parameter->GetType() == tDataType<std::string>()) 
     349    { 
     350      index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>()); 
     351    } 
     352    else if (parameter) 
     353    { 
     354      assert(parameter->GetType() == tDataType<unsigned int>()); 
     355      index = parameter->GetData<unsigned int>(); 
     356    } 
    345357    if (source_type.IsArray() && source_type.GetElementType() == destination_type && index < source_type.GetArraySize()) 
    346358    { 
     
    373385    operation.Continue(intermediate, destination_object); 
    374386  } 
    375 }; 
     387} cGET_LIST_ELEMENT; 
    376388 
    377389class tForEach : public tRegisteredConversionOperation 
     
    393405  { 
    394406    const tType& source_type = source_object.GetType(); 
    395     const tType& destination_type = source_object.GetType(); 
     407    const tType& destination_type = destination_object.GetType(); 
     408    const tType source_element_type = source_type.GetElementType(); 
     409    const tType destination_element_type = destination_type.GetElementType(); 
    396410    size_t size = source_type.IsArray() ? source_type.GetArraySize() : source_object.GetVectorSize(); 
    397411    if (source_type.IsListType() && destination_type.IsListType()) 
     
    402416        tTypedConstPointer source_first = source_object.GetVectorElement(0); 
    403417        tTypedPointer destination_first = destination_object.GetVectorElement(0); 
    404         operation.Continue(source_first, destination_object); 
     418        operation.Continue(source_first, destination_first); 
    405419        if (size > 1) 
    406420        { 
     
    412426          for (size_t i = 2; i < size; i++) 
    413427          { 
    414             source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_type); 
    415             destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_type); 
     428            source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type); 
     429            destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type); 
    416430            operation.Continue(source_next, destination_next); 
    417431          } 
     
    430444      for (size_t i = 0; i < size; i++) 
    431445      { 
    432         tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_type); 
    433         tTypedPointer destination(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_type); 
     446        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type); 
     447        tTypedPointer destination(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type); 
    434448        operation.Continue(source, destination); 
    435449      } 
     
    442456      { 
    443457        size_t source_element_offset = source_type.GetSize() / size; 
    444         tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_type); 
     458        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type); 
    445459        tTypedPointer destination_first = destination_object.GetVectorElement(0); 
    446         operation.Continue(source, destination_object); 
     460        operation.Continue(source, destination_first); 
    447461        if (size > 1) 
    448462        { 
    449           tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_type); 
     463          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type); 
    450464          tTypedPointer destination_next = destination_object.GetVectorElement(1); 
    451465          operation.Continue(source, destination_next); 
     
    453467          for (size_t i = 2; i < size; i++) 
    454468          { 
    455             tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_type); 
    456             destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_type); 
     469            tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type); 
     470            destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type); 
    457471            operation.Continue(source, destination_next); 
    458472          } 
     
    470484    throw std::logic_error("Not supported as single or second operation"); 
    471485  } 
    472 }; 
     486} cFOR_EACH; 
    473487 
    474488class tArrayToVector : public tRegisteredConversionOperation 
     
    499513  { 
    500514    const tType& source_type = source_object.GetType(); 
     515    const tType source_element_type = source_type.GetElementType(); 
    501516    size_t size = source_type.GetArraySize(); 
    502517    destination_object.ResizeVector(size); 
     
    504519    { 
    505520      size_t source_element_offset = source_type.GetSize() / size; 
    506       tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_type); 
     521      tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type); 
    507522      tTypedPointer destination_first = destination_object.GetVectorElement(0); 
    508523      destination_first.DeepCopyFrom(source); 
    509524      if (size > 1) 
    510525      { 
    511         tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_type); 
     526        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type); 
    512527        tTypedPointer destination_next = destination_object.GetVectorElement(1); 
    513528        destination_next.DeepCopyFrom(source); 
     
    515530        for (size_t i = 2; i < size; i++) 
    516531        { 
    517           tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_type); 
     532          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type); 
    518533          destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_next.GetType()); 
    519534          destination_next.DeepCopyFrom(source); 
     
    522537    } 
    523538  } 
    524 }; 
     539} cARRAY_TO_VECTOR; 
    525540 
    526541class tGetTupleElement : public tRegisteredConversionOperation 
     
    532547  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override 
    533548  { 
    534     unsigned int index = parameter ? parameter->GetData<unsigned int>() : 0; 
     549    unsigned int index = 0; 
     550    if (parameter && parameter->GetType() == tDataType<std::string>()) 
     551    { 
     552      index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>()); 
     553    } 
     554    else if (parameter) 
     555    { 
     556      assert(parameter->GetType() == tDataType<unsigned int>()); 
     557      index = parameter->GetData<unsigned int>(); 
     558    } 
    535559    auto tuple_types = source_type.GetTupleTypes(); 
    536560    if (index < tuple_types.second && destination_type == tType(tuple_types.first[index].type_info)) 
     
    540564    return tConversionOption(); 
    541565  } 
    542 }; 
     566} cGET_TUPLE_ELEMENT; 
    543567 
    544568class tWrapByteVectorOperation : public tRegisteredConversionOperation 
     
    567591    rrlib::serialization::tMemoryBuffer& buffer = *destination_object.Get<rrlib::serialization::tMemoryBuffer>(); 
    568592    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>(); 
    569     const rrlib::serialization::tMemoryBuffer temp_buffer(const_cast<uint8_t*>(&vector[0]), vector.size()); 
    570     buffer.CopyFrom(temp_buffer); 
    571   } 
    572  
    573   static constexpr tConversionOption cCONVERSION_OPTION = tConversionOption(tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), false, &FirstConversionFunction, &FinalConversionFunction); 
    574 }; 
     593    buffer = rrlib::serialization::tMemoryBuffer(const_cast<uint8_t*>(&vector[0]), vector.size()); 
     594    //const rrlib::serialization::tMemoryBuffer temp_buffer(const_cast<uint8_t*>(&vector[0]), vector.size()); 
     595    //buffer.CopyFrom(temp_buffer); 
     596  } 
     597 
     598  static constexpr tConversionOption cCONVERSION_OPTION = tConversionOption(tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), true, &FirstConversionFunction, &FinalConversionFunction); 
     599} cWRAP_BYTE_VECTOR; 
    575600 
    576601constexpr tConversionOption tWrapByteVectorOperation::cCONVERSION_OPTION; 
     
    601626    (*destination_object.Get<size_t>()) = source_object.GetVectorSize(); 
    602627  } 
    603 }; 
     628} cLIST_SIZE; 
    604629 
    605630void StringToVectorConversionFunction(const std::string& source, std::vector<char>& destination) 
     
    613638} 
    614639 
    615  
    616 const tToStringOperation cTO_STRING; 
    617 const tStringDeserializationOperation cSTRING_DESERIALIZATION; 
    618 const tBinarySerializationOperation cBINARY_SERIALIZATION; 
    619 const tBinaryDeserializationOperation cBINARY_DESERIALIZATION; 
    620  
    621 const tGetListElement cGET_LIST_ELEMENT; 
    622 const tForEach cFOR_EACH; 
    623 const tArrayToVector cARRAY_TO_VECTOR; 
    624 const tGetTupleElement cGET_TUPLE_ELEMENT; 
    625  
    626 const tWrapByteVectorOperation cWRAP_BYTE_VECTOR; 
    627 const tListSize cLIST_SIZE; 
    628640const tVoidFunctionConversionOperation<std::string, std::vector<char>, decltype(&StringToVectorConversionFunction), &StringToVectorConversionFunction> cSTRING_TO_VECTOR("ToVector"); 
    629641const tVoidFunctionConversionOperation<std::vector<char>, std::string, decltype(&VectorToStringConversionFunction), &VectorToStringConversionFunction> cVECTOR_TO_STRING("MakeString"); 
  • tConversionOperationSequence.cpp

    r8 r9  
    7171 
    7272/*! Enum for binary serialization */ 
    73 enum tOperationSerializationFlags : uint8_t { cFULL_OPERATION = 1, cPARAMETER = 2 }; 
     73enum tOperationSerializationFlags : uint8_t { cFULL_OPERATION = 1, cPARAMETER = 2, cSTRING_PARAMETER = 4 }; 
    7474 
    7575//---------------------------------------------------------------------- 
     
    125125  if (second_operation && ambiguous_operation_lookup[1]) 
    126126  { 
    127     second_operation = &tRegisteredConversionOperation::Find(first_operation->Name(), intermediate_type, destination_type); 
     127    second_operation = &tRegisteredConversionOperation::Find(second_operation->Name(), intermediate_type, destination_type); 
    128128  } 
    129129 
     
    298298  result.operations[1].operation = second_operation; 
    299299  result.destination_type = last_conversion->destination_type; 
     300  static_cast<tConversionOperationSequence&>(result).intermediate_type = this->intermediate_type; 
    300301 
    301302  // Handle special case: only const offsets 
     
    306307    result.fixed_offset_first = static_cast<unsigned int>(conversion1->const_offset_reference_to_source_object + (conversion2 ? conversion2->const_offset_reference_to_source_object : 0)); 
    307308    result.flags = tFlag::cRESULT_INDEPENDENT | tFlag::cRESULT_REFERENCES_SOURCE_DIRECTLY | tFlag::cDEEPCOPY_ONLY; 
    308     return result; 
    309   } 
    310  
    311   // Handle cases where first operation is const offset 
    312   bool first_op_is_const_offset = conversion1->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT; 
    313   result.type_after_first_fixed_offset = first_op_is_const_offset ? conversion1->destination_type : conversion1->source_type; 
    314   if (first_op_is_const_offset) 
    315   { 
    316     result.fixed_offset_first = static_cast<unsigned int>(conversion1->const_offset_reference_to_source_object); 
    317  
    318     // first operation is done, so move second to first 
    319     conversion1 = nullptr; 
    320     std::swap(conversion1, conversion2); 
    321     result.flags |= tFlag::cFIRST_OPERATION_OPTIMIZED_AWAY; 
    322   } 
    323   result.intermediate_type = conversion1->destination_type; 
    324  
    325   // Single operation REFERENCES_SOURCE 
    326   if (conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT && (!conversion2)) 
    327   { 
    328     result.conversion_function_first = allow_reference_to_source ? conversion1->final_conversion_function : conversion1->first_conversion_function; 
    329     result.flags = allow_reference_to_source ? tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY : (tFlag::cRESULT_INDEPENDENT | tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION); 
    330   } 
    331   // First operation is standard or REFERENCES_SOURCE 
    332   else if (conversion1->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION || conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 
    333   { 
    334     result.conversion_function_first = conversion2 ? conversion1->first_conversion_function : conversion1->final_conversion_function; 
    335     result.flags = tFlag::cRESULT_INDEPENDENT; 
    336     if (conversion2 && conversion2->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION) 
    337     { 
    338       result.conversion_function_final = conversion2->final_conversion_function; 
    339     } 
    340     else if (conversion2 && conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
    341     { 
    342       if (conversion2->const_offset_reference_to_source_object == 0 && conversion2->source_type == conversion2->destination_type && (conversion1->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION || allow_reference_to_source)) 
    343       { 
    344         result.conversion_function_first =  conversion1->final_conversion_function; // second operation can be optimized away 
    345         result.intermediate_type = result.destination_type; 
    346         if (conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 
    347         { 
    348           assert(allow_reference_to_source); 
    349           result.flags = tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY; 
    350         } 
    351       } 
    352       else 
    353       { 
    354         result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 
    355         result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 
    356       } 
    357     } 
    358     else if (conversion2 && (conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT || conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT)) 
    359     { 
    360       result.conversion_function_final = conversion2->first_conversion_function; 
    361       result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_SECOND_FUNCTION; 
    362     } 
    363   } 
    364   // First operation is variable offset 
    365   else if (conversion1->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
    366   { 
    367     bool reference_result = allow_reference_to_source && ((!conversion2) || conversion2->type != tConversionOptionType::STANDARD_CONVERSION_FUNCTION); 
    368     if (reference_result) 
    369     { 
    370       if (conversion2 && conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 
    371       { 
    372         result.flags |= tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY; 
    373         result.conversion_function_first = conversion1->first_conversion_function; 
     309  } 
     310  else 
     311  { 
     312    // Handle cases where first operation is const offset 
     313    bool first_op_is_const_offset = conversion1->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT; 
     314    result.type_after_first_fixed_offset = first_op_is_const_offset ? conversion1->destination_type : conversion1->source_type; 
     315    if (first_op_is_const_offset) 
     316    { 
     317      result.fixed_offset_first = static_cast<unsigned int>(conversion1->const_offset_reference_to_source_object); 
     318 
     319      // first operation is done, so move second to first 
     320      conversion1 = nullptr; 
     321      std::swap(conversion1, conversion2); 
     322      result.flags |= tFlag::cFIRST_OPERATION_OPTIMIZED_AWAY; 
     323    } 
     324    result.intermediate_type = conversion1->destination_type; 
     325 
     326    // Single operation REFERENCES_SOURCE 
     327    if (conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT && (!conversion2)) 
     328    { 
     329      result.conversion_function_first = allow_reference_to_source ? conversion1->final_conversion_function : conversion1->first_conversion_function; 
     330      result.flags = allow_reference_to_source ? tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY : (tFlag::cRESULT_INDEPENDENT | tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION); 
     331    } 
     332    // First operation is standard or REFERENCES_SOURCE 
     333    else if (conversion1->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION || conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 
     334    { 
     335      result.conversion_function_first = conversion2 ? conversion1->first_conversion_function : conversion1->final_conversion_function; 
     336      result.flags = tFlag::cRESULT_INDEPENDENT; 
     337      if (conversion2 && conversion2->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION) 
     338      { 
    374339        result.conversion_function_final = conversion2->final_conversion_function; 
    375340      } 
    376       else 
    377       { 
    378         result.flags |= tFlag::cRESULT_REFERENCES_SOURCE_DIRECTLY; 
    379         result.get_destination_reference_function_first = conversion2->destination_reference_function; 
    380         if (conversion2 && conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
    381         { 
     341      else if (conversion2 && conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
     342      { 
     343        if (conversion2->const_offset_reference_to_source_object == 0 && conversion2->source_type == conversion2->destination_type && (conversion1->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION || allow_reference_to_source)) 
     344        { 
     345          result.conversion_function_first =  conversion1->final_conversion_function; // second operation can be optimized away 
     346          result.intermediate_type = result.destination_type; 
     347          if (conversion1->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 
     348          { 
     349            assert(allow_reference_to_source); 
     350            result.flags = tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY; 
     351          } 
     352        } 
     353        else 
     354        { 
     355          result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 
    382356          result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 
    383357        } 
    384         else if (conversion2 && conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
    385         { 
    386           result.get_destination_reference_function_final = conversion2->destination_reference_function; 
    387         } 
    388       } 
    389     } 
    390     else 
    391     { 
    392       result.conversion_function_first = conversion1->first_conversion_function; 
    393       result.flags |= tFlag::cRESULT_INDEPENDENT; 
    394       if (!conversion2) 
    395       { 
    396         result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 
    397       } 
    398       else if (conversion2->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION) 
    399       { 
    400         result.conversion_function_final = conversion2->final_conversion_function; 
    401       } 
    402       else if (conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
    403       { 
    404         result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 
    405         result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 
    406358      } 
    407359      else if (conversion2 && (conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT || conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT)) 
     
    409361        result.conversion_function_final = conversion2->first_conversion_function; 
    410362        result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_SECOND_FUNCTION; 
     363      } 
     364    } 
     365    // First operation is variable offset 
     366    else if (conversion1->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
     367    { 
     368      bool reference_result = allow_reference_to_source && ((!conversion2) || conversion2->type != tConversionOptionType::STANDARD_CONVERSION_FUNCTION); 
     369      if (reference_result) 
     370      { 
     371        if (conversion2 && conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT) 
     372        { 
     373          result.flags |= tFlag::cRESULT_REFERENCES_SOURCE_INTERNALLY; 
     374          result.conversion_function_first = conversion1->first_conversion_function; 
     375          result.conversion_function_final = conversion2->final_conversion_function; 
     376        } 
     377        else 
     378        { 
     379          result.flags |= tFlag::cRESULT_REFERENCES_SOURCE_DIRECTLY; 
     380          result.get_destination_reference_function_first = conversion2->destination_reference_function; 
     381          if (conversion2 && conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
     382          { 
     383            result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 
     384          } 
     385          else if (conversion2 && conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
     386          { 
     387            result.get_destination_reference_function_final = conversion2->destination_reference_function; 
     388          } 
     389        } 
     390      } 
     391      else 
     392      { 
     393        result.conversion_function_first = conversion1->first_conversion_function; 
     394        result.flags |= tFlag::cRESULT_INDEPENDENT; 
     395        if (!conversion2) 
     396        { 
     397          result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 
     398        } 
     399        else if (conversion2->type == tConversionOptionType::STANDARD_CONVERSION_FUNCTION) 
     400        { 
     401          result.conversion_function_final = conversion2->final_conversion_function; 
     402        } 
     403        else if (conversion2->type == tConversionOptionType::CONST_OFFSET_REFERENCE_TO_SOURCE_OBJECT) 
     404        { 
     405          result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_FIRST_FUNCTION; 
     406          result.fixed_offset_final = conversion2->const_offset_reference_to_source_object; 
     407        } 
     408        else if (conversion2 && (conversion2->type == tConversionOptionType::VARIABLE_OFFSET_REFERENCE_TO_SOURCE_OBJECT || conversion2->type == tConversionOptionType::RESULT_REFERENCES_SOURCE_OBJECT)) 
     409        { 
     410          result.conversion_function_final = conversion2->first_conversion_function; 
     411          result.flags |= tFlag::cDO_FINAL_DEEPCOPY_AFTER_SECOND_FUNCTION; 
     412        } 
    411413      } 
    412414    } 
     
    471473    auto operation = sequence[i]; 
    472474    auto parameter_value = sequence.GetParameterValue(i); 
    473     uint8_t flags = (operation.second ? cFULL_OPERATION : 0) | (parameter_value ? cPARAMETER : 0); 
     475    uint8_t flags = (operation.second ? cFULL_OPERATION : 0) | (parameter_value && operation.second && parameter_value.GetType() == operation.second->Parameter().GetType() ? cPARAMETER : (parameter_value ? cSTRING_PARAMETER : 0)); 
    474476    stream.WriteByte(flags); 
    475477    if (operation.second) 
     
    482484      stream << operation.first; 
    483485    } 
    484     if (parameter_value) 
     486    if (flags & cPARAMETER) 
    485487    { 
    486488      parameter_value.Serialize(stream); 
     489    } 
     490    else if (flags & cSTRING_PARAMETER) 
     491    { 
     492      assert(parameter_value.GetType() == tDataType<std::string>()); 
     493      stream << *parameter_value.Get<std::string>(); 
    487494    } 
    488495  } 
     
    534541          throw std::runtime_error("No parameter defined in conversion operation to deserialize"); 
    535542        } 
    536         if ((!sequence.operations[i].parameter)) 
     543        if ((!sequence.operations[i].parameter) || sequence.operations[i].parameter->GetType() != sequence.operations[i].operation->Parameter().GetType()) 
    537544        { 
    538545          sequence.operations[i].parameter.reset(sequence.operations[i].operation->Parameter().GetType().CreateGenericObject()); 
     
    540547        sequence.operations[i].parameter->Deserialize(stream); 
    541548      } 
     549      else if (flags & cSTRING_PARAMETER) 
     550      { 
     551        if (!sequence.operations[i].operation) 
     552        { 
     553          throw std::runtime_error("No conversion operation found"); 
     554        } 
     555        if ((!sequence.operations[i].parameter) || sequence.operations[i].parameter->GetType() != tDataType<std::string>()) 
     556        { 
     557          sequence.operations[i].parameter.reset(tDataType<std::string>().CreateGenericObject()); 
     558        } 
     559        stream >> sequence.operations[i].parameter->GetData<std::string>(); 
     560      } 
    542561      else 
    543562      { 
  • tRegisteredConversionOperation.cpp

    r7 r9  
    7474 
    7575tRegisteredConversionOperation::tRegisteredConversionOperation(util::tManagedConstCharPointer name, const tSupportedTypes& supported_source_types, const tSupportedTypes& supported_destination_types, 
    76     const tConversionOption* single_conversion_option, const tParameterDefinition& parameter) : 
     76    const tConversionOption* single_conversion_option, const tParameterDefinition& parameter, const tRegisteredConversionOperation* not_usually_combined_with) : 
    7777  name(std::move(name)), 
    7878  supported_source_types(supported_source_types), 
    7979  supported_destination_types(supported_destination_types), 
    8080  parameter(parameter), 
    81   single_conversion_option(single_conversion_option) 
     81  single_conversion_option(single_conversion_option), 
     82  not_usually_combined_with_handle(not_usually_combined_with ? not_usually_combined_with->GetHandle() : 0xFFFF) 
    8283{ 
    8384  if (parameter && (!(parameter.GetType().GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE))) 
     
    9495  parameter(), 
    9596  single_conversion_option(nullptr), 
    96   handle(-1) 
     97  handle(-1), 
     98  not_usually_combined_with_handle(0xFFFF) 
    9799{ 
    98100  handle = static_cast<decltype(handle)>(tRegisteredConversionOperation::RegisteredOperations().operations.Add(this)); 
     
    191193    if (name == operation->Name()) 
    192194    { 
    193       auto option = operation->GetConversionOption(source_type, destination_type, nullptr); 
     195      auto option = operation->GetConversionOption((!source_type) && operation->SupportedSourceTypes().filter == tSupportedTypeFilter::SINGLE ? operation->SupportedSourceTypes().single_type : source_type, 
     196                    (!destination_type) && operation->SupportedDestinationTypes().filter == tSupportedTypeFilter::SINGLE ? operation->SupportedDestinationTypes().single_type : destination_type, nullptr); 
    194197      if (option.type != tConversionOptionType::NONE) 
    195198      { 
  • tRegisteredConversionOperation.h

    r8 r9  
    222222 
    223223  /*! 
     224   * \return Handle of conversion operation that this one is not usually combined with (0xFFFF if there is no such operation) 
     225   */ 
     226  uint16_t GetNotUsuallyCombinedWithHandle() const 
     227  { 
     228    return not_usually_combined_with_handle; 
     229  } 
     230 
     231  /*! 
    224232   * \return Registered type conversion operations. 
    225233   */ 
     
    272280   * \param single_conversion_option If operation provides only a single conversion option - points to this option (otherwise override GetConversionOptions()) 
    273281   * \param parameter Any parameter of conversion operation (optional) 
     282   * \param not_usually_combined_with Conversion operation that this one is not usually combined with (a deprecated combination if you want) 
    274283   */ 
    275284  tRegisteredConversionOperation(util::tManagedConstCharPointer name, const tSupportedTypes& supported_source_types, const tSupportedTypes& supported_destination_types, 
    276                                  const tConversionOption* single_conversion_option = nullptr, const tParameterDefinition& parameter = tParameterDefinition()); 
     285                                 const tConversionOption* single_conversion_option = nullptr, const tParameterDefinition& parameter = tParameterDefinition(), 
     286                                 const tRegisteredConversionOperation* not_usually_combined_with = nullptr); 
    277287 
    278288  /*! 
     
    303313  /*! Local handle of operation */ 
    304314  uint16_t handle; 
     315 
     316  /*! Handle of conversion operation that this one is not usually combined with (0xFFFF if there is no such operation) */ 
     317  uint16_t not_usually_combined_with_handle; 
    305318 
    306319 
  • tStaticCastOperation.h

    r7 r9  
    126126    static size_t ComputePointerSourceOffset() 
    127127    { 
    128       const TSource source_object; 
    129       const TDestination& returned_object = static_cast<TDestination&>(source_object); 
     128      const TSource source_object = TSource(); 
     129      const TDestination& returned_object = static_cast<const TDestination&>(source_object); 
    130130      size_t difference = reinterpret_cast<const char*>(&returned_object) - reinterpret_cast<const char*>(&source_object); 
    131131      assert(difference + sizeof(TDestination) <= sizeof(TSource)); 
  • tStaticCastOperation.hpp

    r0 r9  
    7171 
    7272template <typename TSource, typename TDestination> 
    73 const tStaticCastOperation::tStaticCast tStaticCastOperation::tInstanceReferenceStaticOffset<TSource, TDestination>::value({ tConversionOption(tDataType<TSource>(), tDataType<TDestination>(), StaticCastReferencesSourceWithVariableOffset<TSource, TDestination>::value, ComputePointerSourceOffset()) }, IsImplicitlyConvertible<TDestination, TSource>::value); 
     73const tStaticCastOperation::tStaticCast tStaticCastOperation::tInstanceReferenceStaticOffset<TSource, TDestination>::value({ tConversionOption(tDataType<TSource>(), tDataType<TDestination>(), ComputePointerSourceOffset()), IsImplicitlyConvertible<TDestination, TSource>::value }); 
    7474 
    7575template <typename TSource, typename TDestination> 
Note: See TracChangeset for help on using the changeset viewer.