source: rrlib_rtti_conversion/defined_conversions.cpp @ 40:3a50f65e594b

17.03
Last change on this file since 40:3a50f65e594b was 40:3a50f65e594b, checked in by Max Reichardt <mreichardt@…>, 10 months ago

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

File size: 51.9 KB
Line 
1//
2// You received this file as part of RRLib
3// Robotics Research Library
4//
5// Copyright (C) Finroc GbR (finroc.org)
6//
7// This program is free software; you can redistribute it and/or modify
8// it under the terms of the GNU General Public License as published by
9// the Free Software Foundation; either version 2 of the License, or
10// (at your option) any later version.
11//
12// This program is distributed in the hope that it will be useful,
13// but WITHOUT ANY WARRANTY; without even the implied warranty of
14// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15// GNU General Public License for more details.
16//
17// You should have received a copy of the GNU General Public License along
18// with this program; if not, write to the Free Software Foundation, Inc.,
19// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20//
21//----------------------------------------------------------------------
22/*!\file    rrlib/rtti_conversion/defined_conversions.cpp
23 *
24 * \author  Max Reichardt
25 *
26 * \date    2016-08-13
27 *
28 */
29//----------------------------------------------------------------------
30#include "rrlib/rtti_conversion/defined_conversions.h"
31
32//----------------------------------------------------------------------
33// External includes (system with <>, local with "")
34//----------------------------------------------------------------------
35#include <iomanip>
36
37//----------------------------------------------------------------------
38// Internal includes with ""
39//----------------------------------------------------------------------
40#include "rrlib/rtti_conversion/tStaticCastOperation.h"
41#include "rrlib/rtti_conversion/definition/tVoidFunctionConversionOperation.h"
42
43//----------------------------------------------------------------------
44// Debugging
45//----------------------------------------------------------------------
46#include <cassert>
47
48//----------------------------------------------------------------------
49// Namespace usage
50//----------------------------------------------------------------------
51
52//----------------------------------------------------------------------
53// Namespace declaration
54//----------------------------------------------------------------------
55namespace rrlib
56{
57namespace rtti
58{
59namespace conversion
60{
61
62//----------------------------------------------------------------------
63// Forward declarations / typedefs / enums
64//----------------------------------------------------------------------
65
66//----------------------------------------------------------------------
67// Const values
68//----------------------------------------------------------------------
69
70// Register static casts between builtin types
71auto& cBUILTIN_TYPE_CASTS = tStaticCastOperation::
72                            Register<int8_t, int16_t, true, true>()
73                            .Register<int8_t, int32_t, true, true>()
74                            .Register<int8_t, int64_t, true, true>()
75                            .Register<int8_t, uint8_t, true, true>()
76                            .Register<int8_t, uint16_t, true, true>()
77                            .Register<int8_t, uint32_t, true, true>()
78                            .Register<int8_t, uint64_t, true, true>()
79                            .Register<int8_t, float, true, true>()
80                            .Register<int8_t, double, true, true>()
81                            .Register<int8_t, bool, true, true>()
82
83                            .Register<int16_t, int32_t, true, true>()
84                            .Register<int16_t, int64_t, true, true>()
85                            .Register<int16_t, uint8_t, true, true>()
86                            .Register<int16_t, uint16_t, true, true>()
87                            .Register<int16_t, uint32_t, true, true>()
88                            .Register<int16_t, uint64_t, true, true>()
89                            .Register<int16_t, float, true, true>()
90                            .Register<int16_t, double, true, true>()
91                            .Register<int16_t, bool, true, true>()
92
93                            .Register<int32_t, int64_t, true, true>()
94                            .Register<int32_t, uint8_t, true, true>()
95                            .Register<int32_t, uint16_t, true, true>()
96                            .Register<int32_t, uint32_t, true, true>()
97                            .Register<int32_t, uint64_t, true, true>()
98                            .Register<int32_t, float, true, true>()
99                            .Register<int32_t, double, true, true>()
100                            .Register<int32_t, bool, true, true>()
101
102                            .Register<int64_t, uint8_t, true, true>()
103                            .Register<int64_t, uint16_t, true, true>()
104                            .Register<int64_t, uint32_t, true, true>()
105                            .Register<int64_t, uint64_t, true, true>()
106                            .Register<int64_t, float, true, true>()
107                            .Register<int64_t, double, true, true>()
108                            .Register<int64_t, bool, true, true>()
109
110                            .Register<uint8_t, uint16_t, true, true>()
111                            .Register<uint8_t, uint32_t, true, true>()
112                            .Register<uint8_t, uint64_t, true, true>()
113                            .Register<uint8_t, float, true, true>()
114                            .Register<uint8_t, double, true, true>()
115                            .Register<uint8_t, bool, true, true>()
116
117                            .Register<uint16_t, uint32_t, true, true>()
118                            .Register<uint16_t, uint64_t, true, true>()
119                            .Register<uint16_t, float, true, true>()
120                            .Register<uint16_t, double, true, true>()
121                            .Register<uint16_t, bool, true, true>()
122
123                            .Register<uint32_t, uint64_t, true, true>()
124                            .Register<uint32_t, float, true, true>()
125                            .Register<uint32_t, double, true, true>()
126                            .Register<uint32_t, bool, true, true>()
127
128                            .Register<uint64_t, float, true, true>()
129                            .Register<uint64_t, double, true, true>()
130                            .Register<uint64_t, bool, true, true>()
131
132                            .Register<float, double, true, true>()
133                            .Register<float, bool, true, true>()
134
135                            .Register<double, bool, true, true>()
136
137                            .Register<rrlib::serialization::tMemoryBuffer, std::vector<uint8_t>>();
138
139//----------------------------------------------------------------------
140// Implementation
141//----------------------------------------------------------------------
142
143namespace
144{
145
146const unsigned int cSTRING_OPERATION_DEFAULT_FLAGS = 0;
147const rrlib::rtti::tType cBOOL_VECTOR_TYPE = rrlib::rtti::tDataType<std::vector<bool>>();
148
149struct tComputationTypesOperationData
150{
151  tType types[2];
152};
153
154
155class tToStringOperation : public tRegisteredConversionOperation
156{
157public:
158  tToStringOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToString", false), tSupportedTypeFilter::STRING_SERIALIZABLE, tDataType<std::string>(), nullptr, tParameterDefinition("Flags", &cSTRING_OPERATION_DEFAULT_FLAGS, true))
159  {
160  }
161
162  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
163  {
164    if ((source_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && destination_type == tDataType<std::string>())
165    {
166      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
167    }
168    return tConversionOption();
169  }
170
171  static void MainConversionFunction(const tTypedConstPointer& source_object, std::string& destination, const tCurrentConversionOperation& operation)
172  {
173    rrlib::serialization::tStringOutputStream stream;
174
175    // init stream
176    /*auto precision = operation.GetParameterValue(0);
177    if (precision)
178    {
179      stream.GetWrappedStringStream() << std::setprecision(*precision.Get<int>());
180    }*/
181    auto flags = operation.GetParameterValue();
182    if (flags)
183    {
184      unsigned int f = *flags.Get<unsigned int>();
185      if (f)
186      {
187        if (f & eTSF_BOOL_ALPHA)
188        {
189          stream.GetWrappedStringStream() << std::boolalpha;
190        }
191        if (f & eTSF_SHOW_BASE)
192        {
193          stream.GetWrappedStringStream() << std::showbase;
194        }
195        if (f & eTSF_SHOW_POINT)
196        {
197          stream.GetWrappedStringStream() << std::showpoint;
198        }
199        if (f & eTSF_SHOW_POS)
200        {
201          stream.GetWrappedStringStream() << std::showpos;
202        }
203        if (f & eTSF_UPPER_CASE)
204        {
205          stream.GetWrappedStringStream() << std::uppercase;
206        }
207        if (f & eTSF_DEC)
208        {
209          stream.GetWrappedStringStream() << std::dec;
210        }
211        if (f & eTSF_HEX)
212        {
213          stream.GetWrappedStringStream() << std::hex;
214        }
215        if (f & eTSF_OCT)
216        {
217          stream.GetWrappedStringStream() << std::oct;
218        }
219        if (f & eTSF_FIXED)
220        {
221          stream.GetWrappedStringStream() << std::fixed;
222        }
223        if (f & eTSF_SCIENTIFIC)
224        {
225          stream.GetWrappedStringStream() << std::scientific;
226        }
227      }
228    }
229
230    source_object.Serialize(stream);
231    destination = stream.ToString();
232  }
233
234  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
235  {
236    std::string intermediate;
237    MainConversionFunction(source_object, intermediate, operation);
238    operation.Continue(tTypedConstPointer(&intermediate), destination_object);
239  }
240
241  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
242  {
243    MainConversionFunction(source_object, *destination_object.Get<std::string>(), operation);
244  }
245} cTO_STRING;
246
247class tStringDeserializationOperation : public tRegisteredConversionOperation
248{
249public:
250  tStringDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("String Deserialization", false), tDataType<std::string>(), tSupportedTypeFilter::STRING_SERIALIZABLE, nullptr, tParameterDefinition(), &cTO_STRING)
251  {}
252
253  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
254  {
255    if ((destination_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && source_type == tDataType<std::string>())
256    {
257      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
258    }
259    return tConversionOption();
260  }
261
262  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
263  {
264    tType inter_type = operation.compiled_operation.IntermediateType();
265    char intermediate_memory[inter_type.GetSize(true)];
266    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
267    serialization::tStringInputStream stream(*source_object.Get<std::string>());
268    intermediate_object->Deserialize(stream);
269    operation.Continue(*intermediate_object, destination_object);
270  }
271
272  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
273  {
274    serialization::tStringInputStream stream(*source_object.Get<std::string>());
275    destination_object.Deserialize(stream);
276  }
277} cSTRING_DESERIALIZATION;
278
279class tBinarySerializationOperation : public tRegisteredConversionOperation
280{
281public:
282  tBinarySerializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Serialization", false), tSupportedTypeFilter::BINARY_SERIALIZABLE, tDataType<serialization::tMemoryBuffer>())
283  {}
284
285  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
286  {
287    if ((source_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && destination_type == tDataType<serialization::tMemoryBuffer>())
288    {
289      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
290    }
291    return tConversionOption();
292  }
293
294  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
295  {
296    serialization::tStackMemoryBuffer<serialization::cSTACK_BUFFERS_SIZE> buffer;
297    rrlib::serialization::tOutputStream stream(buffer);
298    source_object.Serialize(stream);
299    stream.Close();
300    operation.Continue(tTypedConstPointer(&static_cast<serialization::tMemoryBuffer&>(buffer)), destination_object);
301  }
302
303  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
304  {
305    serialization::tOutputStream stream(*destination_object.Get<serialization::tMemoryBuffer>());
306    destination_object.Serialize(stream);
307  }
308} cBINARY_SERIALIZATION;
309
310class tBinaryDeserializationOperation : public tRegisteredConversionOperation
311{
312public:
313  tBinaryDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Deserialization", false), tDataType<serialization::tMemoryBuffer>(), tSupportedTypeFilter::BINARY_SERIALIZABLE, nullptr, tParameterDefinition(), &cBINARY_SERIALIZATION)
314  {}
315
316  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
317  {
318    if ((destination_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && source_type == tDataType<serialization::tMemoryBuffer>())
319    {
320      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
321    }
322    return tConversionOption();
323  }
324
325  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
326  {
327    tType inter_type = operation.compiled_operation.IntermediateType();
328    char intermediate_memory[inter_type.GetSize(true)];
329    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
330    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
331    intermediate_object->Deserialize(stream);
332    operation.Continue(*intermediate_object, destination_object);
333  }
334
335  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
336  {
337    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
338    destination_object.Deserialize(stream);
339  }
340} cBINARY_DESERIALIZATION;
341
342class tGetListElement : public tRegisteredConversionOperation
343{
344public:
345  tGetListElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("[]", false), tUnderlyingType(tSupportedTypeFilter::GET_LIST_ELEMENT), tSupportedTypeFilter::GET_LIST_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
346  {}
347
348  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
349  {
350    tType check_type = source_type;
351    while (check_type)
352    {
353      if (check_type.IsListType() && check_type.GetElementType() == destination_type)
354      {
355        return tConversionOption(source_type, destination_type, &FirstConversionFunction, &GetDestinationReference);
356      }
357      if (check_type.IsArray() && check_type.GetElementType() == destination_type)
358      {
359        unsigned int index = 0;
360        if (parameter && parameter->GetType() == tDataType<std::string>())
361        {
362          index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>());
363        }
364        else if (parameter)
365        {
366          assert(parameter->GetType() == tDataType<unsigned int>());
367          index = parameter->GetData<unsigned int>();
368        }
369
370        if (index < check_type.GetArraySize())
371        {
372          return tConversionOption(source_type, destination_type, index * check_type.GetElementType().GetSize());
373        }
374      }
375      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
376    }
377    return tConversionOption();
378  }
379
380  static tTypedConstPointer GetDestinationReference(const tTypedConstPointer& source_object, const tCurrentConversionOperation& operation)
381  {
382    auto index_parameter = operation.GetParameterValue();
383    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
384    auto result = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]).GetVectorElement(index);
385    if (!result)
386    {
387      throw std::invalid_argument("Index out of bounds");
388    }
389    return result;
390  }
391
392  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
393  {
394    auto index_parameter = operation.GetParameterValue();
395    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
396    auto intermediate = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]).GetVectorElement(index);
397    if (!intermediate)
398    {
399      throw std::invalid_argument("Index out of bounds");
400    }
401    operation.Continue(intermediate, destination_object);
402  }
403
404  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
405  {
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])
412      {
413        throw std::runtime_error("Source type must be list or array");
414      }
415    }
416    custom_data.Emplace(types_data);
417  }
418
419} cGET_LIST_ELEMENT;
420
421class tForEach : public tRegisteredConversionOperation
422{
423public:
424  tForEach() : tRegisteredConversionOperation(util::tManagedConstCharPointer("For Each", false), tUnderlyingType(tSupportedTypeFilter::FOR_EACH), tUnderlyingType(tSupportedTypeFilter::FOR_EACH))
425  {}
426
427  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
428  {
429    tType check_type = source_type;
430    while (check_type)
431    {
432      if ((check_type.IsListType() || check_type.IsArray()) && destination_type)
433      {
434        return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
435      }
436      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
437    }
438    return tConversionOption();
439  }
440
441  static void FirstConversionFunction(const tTypedConstPointer& source_object_original, const tTypedPointer& destination_object_original, const tCurrentConversionOperation& operation)
442  {
443    tTypedConstPointer source_object = tTypedConstPointer(source_object_original.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]);
444    const tType& source_type = source_object.GetType();
445    tType destination_type = destination_object_original.GetType();
446    while (!(destination_type.IsArray() || destination_type.IsListType()))
447    {
448      destination_type = GetUnderlyingTypeOperationsAreInheritedFrom(destination_type);
449      if (!destination_type)
450      {
451        throw std::runtime_error("Destination type must be list or array type");
452      }
453    }
454    const tTypedPointer destination_object(destination_object_original.GetRawDataPointer(), destination_type);
455    const tType source_element_type = source_type.GetElementType();
456    const tType destination_element_type = destination_type.GetElementType();
457    size_t size = source_type.IsArray() ? source_type.GetArraySize() : source_object.GetVectorSize();
458    if (source_type.IsListType() && destination_type.IsListType())
459    {
460      destination_object.ResizeVector(size);
461      if (size)
462      {
463        if (source_type == cBOOL_VECTOR_TYPE)
464        {
465          bool wrapped_bool = false;
466          tTypedPointer temp_source_pointer(&wrapped_bool);
467          const std::vector<bool>& source = *source_object.Get<std::vector<bool>>();
468
469          wrapped_bool = source[0];
470          tTypedPointer destination_first = destination_object.GetVectorElement(0);
471          operation.Continue(temp_source_pointer, destination_first);
472          if (size > 1)
473          {
474            wrapped_bool = source[1];
475            tTypedPointer destination_next = destination_object.GetVectorElement(1);
476            operation.Continue(temp_source_pointer, destination_next);
477            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
478            for (size_t i = 2; i < size; i++)
479            {
480              wrapped_bool = source[i];
481              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
482              operation.Continue(temp_source_pointer, destination_next);
483            }
484          }
485        }
486        else if (destination_type == cBOOL_VECTOR_TYPE)
487        {
488          bool wrapped_bool = false;
489          tTypedPointer temp_destination_pointer(&wrapped_bool);
490          std::vector<bool>& destination = *destination_object.Get<std::vector<bool>>();
491
492          tTypedConstPointer source_first = source_object.GetVectorElement(0);
493          operation.Continue(source_first, temp_destination_pointer);
494          destination[0] = wrapped_bool;
495          if (size > 1)
496          {
497            tTypedConstPointer source_next = source_object.GetVectorElement(1);
498            operation.Continue(source_next, temp_destination_pointer);
499            size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
500            destination[1] = wrapped_bool;
501            for (size_t i = 2; i < size; i++)
502            {
503              source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
504              operation.Continue(source_next, temp_destination_pointer);
505              destination[i] = wrapped_bool;
506            }
507          }
508        }
509        else
510        {
511          tTypedConstPointer source_first = source_object.GetVectorElement(0);
512          tTypedPointer destination_first = destination_object.GetVectorElement(0);
513          operation.Continue(source_first, destination_first);
514          if (size > 1)
515          {
516            tTypedConstPointer source_next = source_object.GetVectorElement(1);
517            tTypedPointer destination_next = destination_object.GetVectorElement(1);
518            operation.Continue(source_next, destination_next);
519            size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
520            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
521            for (size_t i = 2; i < size; i++)
522            {
523              source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
524              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
525              operation.Continue(source_next, destination_next);
526            }
527          }
528        }
529      }
530    }
531    else if (destination_type.IsArray())
532    {
533      size_t destination_elements = destination_type.GetArraySize();
534      size_t source_elements = source_type.GetTypeClassification() == tTypeClassification::LIST ? source_object.GetVectorSize() : source_type.GetArraySize();
535      size_t copy_elements = std::min(destination_elements, source_elements);
536      size_t fill_elements = destination_elements - copy_elements;
537      size_t destination_element_offset = destination_object.GetType().GetSize() / destination_elements;
538
539      if (source_type == cBOOL_VECTOR_TYPE)
540      {
541        const std::vector<bool>* source = source_object.Get<std::vector<bool>>();
542        bool wrapped_bool = false;
543        tTypedPointer temp_source_pointer(&wrapped_bool);
544        for (size_t i = 0; i < copy_elements; i++)
545        {
546          wrapped_bool = (*source)[i];
547          tTypedPointer destination(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type);
548          operation.Continue(temp_source_pointer, destination);
549        }
550      }
551      else if (source_type.GetTypeClassification() == tTypeClassification::ARRAY)
552      {
553        size_t sources_element_offset = source_object.GetType().GetSize() / source_elements;
554        for (size_t i = 0; i < copy_elements; i++)
555        {
556          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * sources_element_offset, source_element_type);
557          tTypedPointer destination(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type);
558          operation.Continue(source, destination);
559        }
560      }
561      else if (copy_elements > 0)
562      {
563        tTypedConstPointer source_first = source_object.GetVectorElement(0);
564        tTypedPointer destination_first(static_cast<char*>(destination_object.GetRawDataPointer()), destination_element_type);
565        operation.Continue(source_first, destination_first);
566        if (copy_elements > 1)
567        {
568          tTypedConstPointer source_next = source_object.GetVectorElement(1);
569          tTypedPointer destination_second(static_cast<char*>(destination_object.GetRawDataPointer()) + destination_element_offset, destination_element_type);
570          operation.Continue(source_next, destination_second);
571          size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
572          for (size_t i = 2; i < copy_elements; i++)
573          {
574            source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
575            tTypedPointer destination_next(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type);
576            operation.Continue(source_next, destination_next);
577          }
578        }
579      }
580
581      if (fill_elements)
582      {
583        if (destination_element_type.GetTypeTraits() & trait_flags::cIS_DEFAULT_CONSTRUCTION_ZERO_MEMORY)
584        {
585          memset(static_cast<char*>(destination_object.GetRawDataPointer()) + copy_elements * destination_element_offset, 0, fill_elements * destination_element_offset);
586        }
587        else
588        {
589          for (size_t i = 0; i < fill_elements; i++)
590          {
591            destination_element_type.EmplaceInstance(static_cast<char*>(destination_object.GetRawDataPointer()) + (copy_elements + i) * destination_element_offset);
592          }
593        }
594      }
595    }
596    else if (source_type.IsArray() && destination_type.IsListType())
597    {
598      size_t size = source_type.GetArraySize();
599      destination_object.ResizeVector(size);
600      if (size)
601      {
602        size_t source_element_offset = source_type.GetSize() / size;
603        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type);
604
605        if (destination_type == cBOOL_VECTOR_TYPE)
606        {
607          bool wrapped_bool = false;
608          tTypedPointer temp_destination_pointer(&wrapped_bool);
609          std::vector<bool>& destination = *destination_object.Get<std::vector<bool>>();
610
611          operation.Continue(source, temp_destination_pointer);
612          destination[0] = wrapped_bool;
613          if (size > 1)
614          {
615            tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
616            operation.Continue(source, temp_destination_pointer);
617            destination[1] = wrapped_bool;
618            for (size_t i = 2; i < size; i++)
619            {
620              tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
621              operation.Continue(source, temp_destination_pointer);
622              destination[i] = wrapped_bool;
623            }
624          }
625        }
626        else
627        {
628          tTypedPointer destination_first = destination_object.GetVectorElement(0);
629          operation.Continue(source, destination_first);
630          if (size > 1)
631          {
632            tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
633            tTypedPointer destination_next = destination_object.GetVectorElement(1);
634            operation.Continue(source, destination_next);
635            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
636            for (size_t i = 2; i < size; i++)
637            {
638              tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
639              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
640              operation.Continue(source, destination_next);
641            }
642          }
643        }
644      }
645    }
646    else
647    {
648      throw std::runtime_error("Unsupported types for 'For Each' Operation");
649    }
650  }
651
652  __attribute__((__noreturn__)) static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
653  {
654    throw std::logic_error("Not supported as single or second operation");
655  }
656
657  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
658  {
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])
665      {
666        throw std::runtime_error("Source type must be list or array");
667      }
668    }
669    custom_data.Emplace(types_data);
670  }
671
672} cFOR_EACH;
673
674class tArrayToVector : public tRegisteredConversionOperation
675{
676public:
677  tArrayToVector() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToVector", false), tUnderlyingType(tSupportedTypeFilter::ARRAY_TO_VECTOR), tSupportedTypeFilter::ARRAY_TO_VECTOR)
678  {}
679
680  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
681  {
682    tType check_type = source_type;
683    while (check_type)
684    {
685      if (check_type.IsArray() && destination_type.IsListType() && check_type.GetElementType() == destination_type.GetElementType())
686      {
687        return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
688      }
689      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
690    }
691    return tConversionOption();
692  }
693
694  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
695  {
696    tType inter_type = operation.compiled_operation.IntermediateType();
697    char intermediate_memory[inter_type.GetSize(true)];
698    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
699    FinalConversionFunction(source_object, *intermediate_object, operation);
700    operation.Continue(*intermediate_object, destination_object);
701  }
702
703  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
704  {
705    const tType& source_type = operation.GetCustomData().Get<tComputationTypesOperationData>().types[0];
706    const tType source_element_type = source_type.GetElementType();
707    size_t size = source_type.GetArraySize();
708    destination_object.ResizeVector(size);
709    if (size)
710    {
711      size_t source_element_offset = source_type.GetSize() / size;
712      tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type);
713      tTypedPointer destination_first = destination_object.GetVectorElement(0);
714      destination_first.DeepCopyFrom(source);
715      if (size > 1)
716      {
717        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
718        tTypedPointer destination_next = destination_object.GetVectorElement(1);
719        destination_next.DeepCopyFrom(source);
720        size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
721        for (size_t i = 2; i < size; i++)
722        {
723          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
724          destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_next.GetType());
725          destination_next.DeepCopyFrom(source);
726        }
727      }
728    }
729  }
730
731  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
732  {
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])
739      {
740        throw std::runtime_error("Source type must be array");
741      }
742    }
743    custom_data.Emplace(types_data);
744  }
745} cARRAY_TO_VECTOR;
746
747class tGetTupleElement : public tRegisteredConversionOperation
748{
749public:
750  tGetTupleElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("get", false), tUnderlyingType(tSupportedTypeFilter::GET_TUPLE_ELEMENT), tSupportedTypeFilter::GET_TUPLE_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
751  {}
752
753  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
754  {
755    unsigned int index = 0;
756    if (parameter && parameter->GetType() == tDataType<std::string>())
757    {
758      index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>());
759    }
760    else if (parameter)
761    {
762      assert(parameter->GetType() == tDataType<unsigned int>());
763      index = parameter->GetData<unsigned int>();
764    }
765
766    tType check_type = source_type;
767    while (check_type)
768    {
769      auto tuple_types = check_type.GetTupleTypes();
770      if (index < tuple_types.second && destination_type == tType(tuple_types.first[index].type_info))
771      {
772        return tConversionOption(source_type, destination_type, tuple_types.first[index].offset);
773      }
774      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
775    }
776
777    return tConversionOption();
778  }
779} cGET_TUPLE_ELEMENT;
780
781class tWrapByteVectorOperation : public tRegisteredConversionOperation
782{
783public:
784  tWrapByteVectorOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Wrap", false), tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), &cCONVERSION_OPTION)
785  {}
786
787  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
788  {
789    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>();
790    if (vector.size())
791    {
792      const rrlib::serialization::tMemoryBuffer buffer(const_cast<uint8_t*>(&vector[0]), vector.size());
793      operation.Continue(tTypedConstPointer(&buffer), destination_object);
794    }
795    else
796    {
797      const rrlib::serialization::tMemoryBuffer buffer(0);
798      operation.Continue(tTypedConstPointer(&buffer), destination_object);
799    }
800  }
801
802  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
803  {
804    rrlib::serialization::tMemoryBuffer& buffer = *destination_object.Get<rrlib::serialization::tMemoryBuffer>();
805    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>();
806    buffer = rrlib::serialization::tMemoryBuffer(const_cast<uint8_t*>(&vector[0]), vector.size());
807    //const rrlib::serialization::tMemoryBuffer temp_buffer(const_cast<uint8_t*>(&vector[0]), vector.size());
808    //buffer.CopyFrom(temp_buffer);
809  }
810
811  static constexpr tConversionOption cCONVERSION_OPTION = tConversionOption(tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), true, &FirstConversionFunction, &FinalConversionFunction);
812} cWRAP_BYTE_VECTOR;
813
814constexpr tConversionOption tWrapByteVectorOperation::cCONVERSION_OPTION;
815
816class tListSize : public tRegisteredConversionOperation
817{
818public:
819  tListSize() : tRegisteredConversionOperation(util::tManagedConstCharPointer("size()", false), tUnderlyingType(tSupportedTypeFilter::LISTS), tDataType<size_t>())
820  {}
821
822  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
823  {
824    tType check_type = source_type;
825    while (check_type)
826    {
827      if (check_type.IsListType() && destination_type == tDataType<size_t>())
828      {
829        return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
830      }
831      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
832    }
833    return tConversionOption();
834  }
835
836  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
837  {
838    size_t size = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]).GetVectorSize();
839    operation.Continue(tTypedConstPointer(&size), destination_object);
840  }
841
842  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
843  {
844    (*destination_object.Get<size_t>()) = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().Get<tComputationTypesOperationData>().types[0]).GetVectorSize();
845  }
846
847  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
848  {
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])
855      {
856        throw std::runtime_error("Source type must be list");
857      }
858    }
859    custom_data.Emplace(types_data);
860  }
861} cLIST_SIZE;
862
863void StringToVectorConversionFunction(const std::string& source, std::vector<char>& destination)
864{
865  destination = std::vector<char>(source.begin(), source.end());
866}
867
868void VectorToStringConversionFunction(const std::vector<char>& source, std::string& destination)
869{
870  destination = std::string(source.begin(), source.end());
871}
872
873const tVoidFunctionConversionOperation<std::string, std::vector<char>, decltype(&StringToVectorConversionFunction), &StringToVectorConversionFunction> cSTRING_TO_VECTOR("ToVector");
874const tVoidFunctionConversionOperation<std::vector<char>, std::string, decltype(&VectorToStringConversionFunction), &VectorToStringConversionFunction> cVECTOR_TO_STRING("MakeString");
875
876class tAdjustLength : public tRegisteredConversionOperation
877{
878public:
879  tAdjustLength() : tRegisteredConversionOperation(util::tManagedConstCharPointer("AdjustLength", false), tUnderlyingType(tSupportedTypeFilter::ADJUST_LENGTH), tUnderlyingType(tSupportedTypeFilter::ADJUST_LENGTH))
880  {}
881
882  static tType GetSupportedType(const tType& type, bool source_type)
883  {
884    return (!type) ? tType() : ((type.IsArray() || (source_type && type.IsListType())) ? type : GetSupportedType(GetUnderlyingTypeOperationsAreInheritedFrom(type), source_type));
885  }
886
887  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
888  {
889    tType supported_source_type = GetSupportedType(source_type, true);
890    tType supported_destination_type = GetSupportedType(destination_type, true);
891    if (supported_source_type && supported_destination_type && supported_source_type.GetElementType() == supported_destination_type.GetElementType())
892    {
893      const auto cQUICK_FLAGS = trait_flags::cIS_DEFAULT_CONSTRUCTION_ZERO_MEMORY | trait_flags::cSUPPORTS_BITWISE_COPY;
894      bool quick = (supported_source_type.GetElementType().GetTypeTraits() & cQUICK_FLAGS) == cQUICK_FLAGS;
895      assert(supported_destination_type.IsArray());
896      if (supported_source_type.IsArray() && quick)
897      {
898        if (supported_destination_type.GetSize() > supported_source_type.GetSize())
899        {
900          return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionMemset<&FinalConversionFunctionArrayMemcpy<true>>, &FinalConversionFunctionArrayMemcpy<true>);
901        }
902        else
903        {
904          return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionMemset<&FinalConversionFunctionArrayMemcpy<false>>, &FinalConversionFunctionArrayMemcpy<false>);
905        }
906      }
907      else if (supported_source_type == tDataType<std::vector<bool>>())
908      {
909        return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionMemset<&FinalConversionFunctionBoolVector>, &FinalConversionFunctionBoolVector);
910      }
911      else if (supported_source_type.IsArray())
912      {
913        return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionStandard<&FinalConversionFunctionArray>, &FinalConversionFunctionArray);
914      }
915
916      assert(supported_source_type.IsListType());
917      if (quick)
918      {
919        return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionMemset<&FinalConversionFunctionVector<true>>, &FinalConversionFunctionVector<true>);
920      }
921      return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionStandard<&FinalConversionFunctionVector<false>>, &FinalConversionFunctionVector<false>);
922    }
923    return tConversionOption();
924  }
925
926  template <tConversionOption::tConversionFunction Tfinal_conversion>
927  static void FirstConversionFunctionMemset(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
928  {
929    tType inter_type = operation.compiled_operation.IntermediateType();
930    char intermediate_memory[inter_type.GetSize()];
931    memset(intermediate_memory, 0, sizeof(intermediate_memory));
932    tTypedPointer intermediate_object(intermediate_memory, inter_type);
933    (*Tfinal_conversion)(source_object, intermediate_object, operation);
934    operation.Continue(intermediate_object, destination_object);
935  }
936
937  template <tConversionOption::tConversionFunction Tfinal_conversion>
938  static void FirstConversionFunctionStandard(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
939  {
940    tType inter_type = operation.compiled_operation.IntermediateType();
941    char intermediate_memory[inter_type.GetSize(true)];
942    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
943    (*Tfinal_conversion)(source_object, *intermediate_object, operation);
944    operation.Continue(*intermediate_object, destination_object);
945  }
946
947  template <bool Tdestination_larger>
948  static void FinalConversionFunctionArrayMemcpy(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
949  {
950    if (Tdestination_larger)
951    {
952      size_t destination_size = destination_object.GetType().GetSize();
953      size_t copy_size = std::min(source_object.GetType().GetSize(), destination_size);
954      size_t fill_size = destination_size - source_object.GetType().GetSize();
955      memcpy(destination_object.GetRawDataPointer(), source_object.GetRawDataPointer(), copy_size);
956      memset(static_cast<char*>(destination_object.GetRawDataPointer()) + copy_size, 0, fill_size);
957    }
958    else
959    {
960      memcpy(destination_object.GetRawDataPointer(), source_object.GetRawDataPointer(), destination_object.GetType().GetSize());
961    }
962  }
963
964  static void FinalConversionFunctionArray(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
965  {
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];
969    const tType element_type = source_type.GetElementType();
970    size_t element_size = element_type.GetSize();
971    bool destination_larger = destination_type > source_type;
972    size_t copy_size = std::min(source_type.GetArraySize(), destination_type.GetArraySize());
973
974    for (size_t i = 0; i < copy_size; i++)
975    {
976      tTypedConstPointer source_element(static_cast<const char*>(source_object.GetRawDataPointer()) + i * element_size, element_type);
977      tTypedPointer destination_element(static_cast<char*>(destination_object.GetRawDataPointer()) + i * element_size, element_type);
978      destination_element.DeepCopyFrom(source_element);
979    }
980
981    if (destination_larger)
982    {
983      for (size_t i = copy_size; i < destination_type.GetArraySize(); i++)
984      {
985        element_type.EmplaceInstance(static_cast<char*>(destination_object.GetRawDataPointer()) + i * element_size);
986      }
987    }
988  }
989
990  static void FinalConversionFunctionBoolVector(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
991  {
992    const std::vector<bool>* source = source_object.GetUnchecked<std::vector<bool>>();
993    const tType destination_type = operation.GetCustomData().Get<tComputationTypesOperationData>().types[1];
994    size_t destination_elements = destination_type.GetArraySize();
995
996    size_t copy_elements = std::min(source->size(), destination_elements);
997    size_t fill_elements = destination_elements - copy_elements;
998
999    for (size_t i = 0; i < copy_elements; i++)
1000    {
1001      *(static_cast<bool*>(destination_object.GetRawDataPointer()) + i) = (*source)[i];
1002    }
1003    memset(static_cast<bool*>(destination_object.GetRawDataPointer()) + copy_elements, 0, fill_elements);
1004  }
1005
1006  template <bool Tmemcpy>
1007  static void FinalConversionFunctionVector(const tTypedConstPointer& source_object_original, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
1008  {
1009    auto custom_data = operation.GetCustomData();
1010    const tType destination_type = custom_data.Get<tComputationTypesOperationData>().types[1];
1011    const tType element_type = destination_type.GetElementType();
1012    tTypedConstPointer source_object(source_object_original.GetRawDataPointer(), custom_data.Get<tComputationTypesOperationData>().types[0]);
1013
1014    size_t copy_elements = std::min(source_object.GetVectorSize(), destination_type.GetArraySize());
1015    size_t fill_elements = destination_type.GetArraySize() - copy_elements;
1016
1017    if (copy_elements > 0)
1018    {
1019      tTypedConstPointer source_first = source_object.GetVectorElement(0);
1020      if (Tmemcpy)
1021      {
1022        memcpy(destination_object.GetRawDataPointer(), source_first.GetRawDataPointer(), element_type.GetSize());
1023      }
1024      else
1025      {
1026        tTypedPointer destination_element(static_cast<char*>(destination_object.GetRawDataPointer()), element_type);
1027        destination_element.DeepCopyFrom(source_first);
1028      }
1029
1030      if (copy_elements > 1)
1031      {
1032        tTypedConstPointer source_next = source_object.GetVectorElement(1);
1033        if (Tmemcpy)
1034        {
1035          memcpy(static_cast<char*>(destination_object.GetRawDataPointer()) + element_type.GetSize(), source_next.GetRawDataPointer(), element_type.GetSize());
1036        }
1037        else
1038        {
1039          tTypedPointer destination_element(static_cast<char*>(destination_object.GetRawDataPointer()) + element_type.GetSize(), element_type);
1040          destination_element.DeepCopyFrom(source_next);
1041        }
1042        size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
1043        for (size_t i = 2; i < copy_elements; i++)
1044        {
1045          source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, element_type);
1046          if (Tmemcpy)
1047          {
1048            memcpy(static_cast<char*>(destination_object.GetRawDataPointer()) + i * element_type.GetSize(), source_next.GetRawDataPointer(), element_type.GetSize());
1049          }
1050          else
1051          {
1052            tTypedPointer destination_element(static_cast<char*>(destination_object.GetRawDataPointer()) + i * element_type.GetSize(), element_type);
1053            destination_element.DeepCopyFrom(source_next);
1054          }
1055        }
1056      }
1057    }
1058
1059    if (fill_elements)
1060    {
1061      if (element_type.GetTypeTraits() & trait_flags::cIS_DEFAULT_CONSTRUCTION_ZERO_MEMORY)
1062      {
1063        size_t offset = copy_elements * element_type.GetSize();
1064        memset(static_cast<char*>(destination_object.GetRawDataPointer()) + offset, 0, destination_type.GetSize() - offset);
1065      }
1066      else
1067      {
1068        for (size_t i = 0; i < fill_elements; i++)
1069        {
1070          element_type.EmplaceInstance(static_cast<char*>(destination_object.GetRawDataPointer()) + (copy_elements + i) * element_type.GetSize());
1071        }
1072      }
1073    }
1074  }
1075
1076  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
1077  {
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);
1082  }
1083
1084} cADJUST_LENGTH;
1085
1086}
1087
1088const tRegisteredConversionOperation& cTO_STRING_OPERATION = cTO_STRING;
1089const tRegisteredConversionOperation& cSTRING_DESERIALIZATION_OPERATION = cSTRING_DESERIALIZATION;
1090const tRegisteredConversionOperation& cBINARY_SERIALIZATION_OPERATION = cBINARY_SERIALIZATION;
1091const tRegisteredConversionOperation& cBINARY_DESERIALIZATION_OPERATION = cBINARY_DESERIALIZATION;
1092
1093const tRegisteredConversionOperation& cGET_LIST_ELEMENT_OPERATION = cGET_LIST_ELEMENT;
1094const tRegisteredConversionOperation& cFOR_EACH_OPERATION = cFOR_EACH;
1095const tRegisteredConversionOperation& cARRAY_TO_VECTOR_OPERATION = cARRAY_TO_VECTOR;
1096const tRegisteredConversionOperation& cGET_TUPLE_ELEMENT_OPERATION = cGET_TUPLE_ELEMENT;
1097
1098const tRegisteredConversionOperation& cWRAP_BYTE_VECTOR_OPERATION = cWRAP_BYTE_VECTOR;
1099const tRegisteredConversionOperation& cLIST_SIZE_OPERATION = cLIST_SIZE;
1100const tRegisteredConversionOperation& cSTRING_TO_VECTOR_OPERATION = cSTRING_TO_VECTOR;
1101const tRegisteredConversionOperation& cMAKE_STRING_OPERATION = cVECTOR_TO_STRING;
1102const tRegisteredConversionOperation& cADJUST_LENGTH_OPERATION = cADJUST_LENGTH;
1103
1104
1105//----------------------------------------------------------------------
1106// End of namespace declaration
1107//----------------------------------------------------------------------
1108}
1109}
1110}
Note: See TracBrowser for help on using the repository browser.