source: rrlib_rtti_conversion/defined_conversions.cpp @ 38:ae1ecd302f54

17.03
Last change on this file since 38:ae1ecd302f54 was 38:ae1ecd302f54, checked in by Max Reichardt <mreichardt@…>, 12 months ago

Fixes bug in for-each conversion operation (when converting from std::vector to std::array) - as well as a few clang compiler warnings (missing 'override')

File size: 51.5 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
149
150class tToStringOperation : public tRegisteredConversionOperation
151{
152public:
153  tToStringOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToString", false), tSupportedTypeFilter::STRING_SERIALIZABLE, tDataType<std::string>(), nullptr, tParameterDefinition("Flags", &cSTRING_OPERATION_DEFAULT_FLAGS, true))
154  {
155  }
156
157  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
158  {
159    if ((source_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && destination_type == tDataType<std::string>())
160    {
161      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
162    }
163    return tConversionOption();
164  }
165
166  static void MainConversionFunction(const tTypedConstPointer& source_object, std::string& destination, const tCurrentConversionOperation& operation)
167  {
168    rrlib::serialization::tStringOutputStream stream;
169
170    // init stream
171    /*auto precision = operation.GetParameterValue(0);
172    if (precision)
173    {
174      stream.GetWrappedStringStream() << std::setprecision(*precision.Get<int>());
175    }*/
176    auto flags = operation.GetParameterValue();
177    if (flags)
178    {
179      unsigned int f = *flags.Get<unsigned int>();
180      if (f)
181      {
182        if (f & eTSF_BOOL_ALPHA)
183        {
184          stream.GetWrappedStringStream() << std::boolalpha;
185        }
186        if (f & eTSF_SHOW_BASE)
187        {
188          stream.GetWrappedStringStream() << std::showbase;
189        }
190        if (f & eTSF_SHOW_POINT)
191        {
192          stream.GetWrappedStringStream() << std::showpoint;
193        }
194        if (f & eTSF_SHOW_POS)
195        {
196          stream.GetWrappedStringStream() << std::showpos;
197        }
198        if (f & eTSF_UPPER_CASE)
199        {
200          stream.GetWrappedStringStream() << std::uppercase;
201        }
202        if (f & eTSF_DEC)
203        {
204          stream.GetWrappedStringStream() << std::dec;
205        }
206        if (f & eTSF_HEX)
207        {
208          stream.GetWrappedStringStream() << std::hex;
209        }
210        if (f & eTSF_OCT)
211        {
212          stream.GetWrappedStringStream() << std::oct;
213        }
214        if (f & eTSF_FIXED)
215        {
216          stream.GetWrappedStringStream() << std::fixed;
217        }
218        if (f & eTSF_SCIENTIFIC)
219        {
220          stream.GetWrappedStringStream() << std::scientific;
221        }
222      }
223    }
224
225    source_object.Serialize(stream);
226    destination = stream.ToString();
227  }
228
229  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
230  {
231    std::string intermediate;
232    MainConversionFunction(source_object, intermediate, operation);
233    operation.Continue(tTypedConstPointer(&intermediate), destination_object);
234  }
235
236  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
237  {
238    MainConversionFunction(source_object, *destination_object.Get<std::string>(), operation);
239  }
240} cTO_STRING;
241
242class tStringDeserializationOperation : public tRegisteredConversionOperation
243{
244public:
245  tStringDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("String Deserialization", false), tDataType<std::string>(), tSupportedTypeFilter::STRING_SERIALIZABLE, nullptr, tParameterDefinition(), &cTO_STRING)
246  {}
247
248  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
249  {
250    if ((destination_type.GetTypeTraits() & trait_flags::cIS_STRING_SERIALIZABLE) && source_type == tDataType<std::string>())
251    {
252      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
253    }
254    return tConversionOption();
255  }
256
257  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
258  {
259    tType inter_type = operation.compiled_operation.IntermediateType();
260    char intermediate_memory[inter_type.GetSize(true)];
261    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
262    serialization::tStringInputStream stream(*source_object.Get<std::string>());
263    intermediate_object->Deserialize(stream);
264    operation.Continue(*intermediate_object, destination_object);
265  }
266
267  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
268  {
269    serialization::tStringInputStream stream(*source_object.Get<std::string>());
270    destination_object.Deserialize(stream);
271  }
272} cSTRING_DESERIALIZATION;
273
274class tBinarySerializationOperation : public tRegisteredConversionOperation
275{
276public:
277  tBinarySerializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Serialization", false), tSupportedTypeFilter::BINARY_SERIALIZABLE, tDataType<serialization::tMemoryBuffer>())
278  {}
279
280  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
281  {
282    if ((source_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && destination_type == tDataType<serialization::tMemoryBuffer>())
283    {
284      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
285    }
286    return tConversionOption();
287  }
288
289  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
290  {
291    serialization::tStackMemoryBuffer<serialization::cSTACK_BUFFERS_SIZE> buffer;
292    rrlib::serialization::tOutputStream stream(buffer);
293    source_object.Serialize(stream);
294    stream.Close();
295    operation.Continue(tTypedConstPointer(&static_cast<serialization::tMemoryBuffer&>(buffer)), destination_object);
296  }
297
298  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
299  {
300    serialization::tOutputStream stream(*destination_object.Get<serialization::tMemoryBuffer>());
301    destination_object.Serialize(stream);
302  }
303} cBINARY_SERIALIZATION;
304
305class tBinaryDeserializationOperation : public tRegisteredConversionOperation
306{
307public:
308  tBinaryDeserializationOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Binary Deserialization", false), tDataType<serialization::tMemoryBuffer>(), tSupportedTypeFilter::BINARY_SERIALIZABLE, nullptr, tParameterDefinition(), &cBINARY_SERIALIZATION)
309  {}
310
311  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
312  {
313    if ((destination_type.GetTypeTraits() & trait_flags::cIS_BINARY_SERIALIZABLE) && source_type == tDataType<serialization::tMemoryBuffer>())
314    {
315      return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
316    }
317    return tConversionOption();
318  }
319
320  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
321  {
322    tType inter_type = operation.compiled_operation.IntermediateType();
323    char intermediate_memory[inter_type.GetSize(true)];
324    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
325    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
326    intermediate_object->Deserialize(stream);
327    operation.Continue(*intermediate_object, destination_object);
328  }
329
330  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
331  {
332    serialization::tInputStream stream(*source_object.Get<serialization::tMemoryBuffer>());
333    destination_object.Deserialize(stream);
334  }
335} cBINARY_DESERIALIZATION;
336
337class tGetListElement : public tRegisteredConversionOperation
338{
339public:
340  tGetListElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("[]", false), tUnderlyingType(tSupportedTypeFilter::GET_LIST_ELEMENT), tSupportedTypeFilter::GET_LIST_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
341  {}
342
343  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
344  {
345    tType check_type = source_type;
346    while (check_type)
347    {
348      if (check_type.IsListType() && check_type.GetElementType() == destination_type)
349      {
350        return tConversionOption(source_type, destination_type, &FirstConversionFunction, &GetDestinationReference);
351      }
352      if (check_type.IsArray() && check_type.GetElementType() == destination_type)
353      {
354        unsigned int index = 0;
355        if (parameter && parameter->GetType() == tDataType<std::string>())
356        {
357          index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>());
358        }
359        else if (parameter)
360        {
361          assert(parameter->GetType() == tDataType<unsigned int>());
362          index = parameter->GetData<unsigned int>();
363        }
364
365        if (index < check_type.GetArraySize())
366        {
367          return tConversionOption(source_type, destination_type, index * check_type.GetElementType().GetSize());
368        }
369      }
370      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
371    }
372    return tConversionOption();
373  }
374
375  static tTypedConstPointer GetDestinationReference(const tTypedConstPointer& source_object, const tCurrentConversionOperation& operation)
376  {
377    auto index_parameter = operation.GetParameterValue();
378    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
379    auto result = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]).GetVectorElement(index);
380    if (!result)
381    {
382      throw std::invalid_argument("Index out of bounds");
383    }
384    return result;
385  }
386
387  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
388  {
389    auto index_parameter = operation.GetParameterValue();
390    unsigned int index = index_parameter ? (*index_parameter.Get<unsigned int>()) : 0;
391    auto intermediate = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]).GetVectorElement(index);
392    if (!intermediate)
393    {
394      throw std::invalid_argument("Index out of bounds");
395    }
396    operation.Continue(intermediate, destination_object);
397  }
398
399  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
400  {
401    custom_data.ComputationTypes()[0] = conversion_option.source_type;
402    while (!(custom_data.ComputationTypes()[0].IsListType() || custom_data.ComputationTypes()[0].IsArray()))
403    {
404      custom_data.ComputationTypes()[0] = GetUnderlyingTypeOperationsAreInheritedFrom(custom_data.ComputationTypes()[0]);
405      if (!custom_data.ComputationTypes()[0])
406      {
407        throw std::runtime_error("Source type must be list or array");
408      }
409    }
410  }
411
412} cGET_LIST_ELEMENT;
413
414class tForEach : public tRegisteredConversionOperation
415{
416public:
417  tForEach() : tRegisteredConversionOperation(util::tManagedConstCharPointer("For Each", false), tUnderlyingType(tSupportedTypeFilter::FOR_EACH), tUnderlyingType(tSupportedTypeFilter::FOR_EACH))
418  {}
419
420  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
421  {
422    tType check_type = source_type;
423    while (check_type)
424    {
425      if ((check_type.IsListType() || check_type.IsArray()) && destination_type)
426      {
427        return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
428      }
429      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
430    }
431    return tConversionOption();
432  }
433
434  static void FirstConversionFunction(const tTypedConstPointer& source_object_original, const tTypedPointer& destination_object_original, const tCurrentConversionOperation& operation)
435  {
436    tTypedConstPointer source_object = tTypedConstPointer(source_object_original.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]);
437    const tType& source_type = source_object.GetType();
438    tType destination_type = destination_object_original.GetType();
439    while (!(destination_type.IsArray() || destination_type.IsListType()))
440    {
441      destination_type = GetUnderlyingTypeOperationsAreInheritedFrom(destination_type);
442      if (!destination_type)
443      {
444        throw std::runtime_error("Destination type must be list or array type");
445      }
446    }
447    const tTypedPointer destination_object(destination_object_original.GetRawDataPointer(), destination_type);
448    const tType source_element_type = source_type.GetElementType();
449    const tType destination_element_type = destination_type.GetElementType();
450    size_t size = source_type.IsArray() ? source_type.GetArraySize() : source_object.GetVectorSize();
451    if (source_type.IsListType() && destination_type.IsListType())
452    {
453      destination_object.ResizeVector(size);
454      if (size)
455      {
456        if (source_type == cBOOL_VECTOR_TYPE)
457        {
458          bool wrapped_bool = false;
459          tTypedPointer temp_source_pointer(&wrapped_bool);
460          const std::vector<bool>& source = *source_object.Get<std::vector<bool>>();
461
462          wrapped_bool = source[0];
463          tTypedPointer destination_first = destination_object.GetVectorElement(0);
464          operation.Continue(temp_source_pointer, destination_first);
465          if (size > 1)
466          {
467            wrapped_bool = source[1];
468            tTypedPointer destination_next = destination_object.GetVectorElement(1);
469            operation.Continue(temp_source_pointer, destination_next);
470            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
471            for (size_t i = 2; i < size; i++)
472            {
473              wrapped_bool = source[i];
474              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
475              operation.Continue(temp_source_pointer, destination_next);
476            }
477          }
478        }
479        else if (destination_type == cBOOL_VECTOR_TYPE)
480        {
481          bool wrapped_bool = false;
482          tTypedPointer temp_destination_pointer(&wrapped_bool);
483          std::vector<bool>& destination = *destination_object.Get<std::vector<bool>>();
484
485          tTypedConstPointer source_first = source_object.GetVectorElement(0);
486          operation.Continue(source_first, temp_destination_pointer);
487          destination[0] = wrapped_bool;
488          if (size > 1)
489          {
490            tTypedConstPointer source_next = source_object.GetVectorElement(1);
491            operation.Continue(source_next, temp_destination_pointer);
492            size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
493            destination[1] = wrapped_bool;
494            for (size_t i = 2; i < size; i++)
495            {
496              source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
497              operation.Continue(source_next, temp_destination_pointer);
498              destination[i] = wrapped_bool;
499            }
500          }
501        }
502        else
503        {
504          tTypedConstPointer source_first = source_object.GetVectorElement(0);
505          tTypedPointer destination_first = destination_object.GetVectorElement(0);
506          operation.Continue(source_first, destination_first);
507          if (size > 1)
508          {
509            tTypedConstPointer source_next = source_object.GetVectorElement(1);
510            tTypedPointer destination_next = destination_object.GetVectorElement(1);
511            operation.Continue(source_next, destination_next);
512            size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
513            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
514            for (size_t i = 2; i < size; i++)
515            {
516              source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
517              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
518              operation.Continue(source_next, destination_next);
519            }
520          }
521        }
522      }
523    }
524    else if (destination_type.IsArray())
525    {
526      size_t destination_elements = destination_type.GetArraySize();
527      size_t source_elements = source_type.GetTypeClassification() == tTypeClassification::LIST ? source_object.GetVectorSize() : source_type.GetArraySize();
528      size_t copy_elements = std::min(destination_elements, source_elements);
529      size_t fill_elements = destination_elements - copy_elements;
530      size_t destination_element_offset = destination_object.GetType().GetSize() / destination_elements;
531
532      if (source_type == cBOOL_VECTOR_TYPE)
533      {
534        const std::vector<bool>* source = source_object.Get<std::vector<bool>>();
535        bool wrapped_bool = false;
536        tTypedPointer temp_source_pointer(&wrapped_bool);
537        for (size_t i = 0; i < copy_elements; i++)
538        {
539          wrapped_bool = (*source)[i];
540          tTypedPointer destination(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type);
541          operation.Continue(temp_source_pointer, destination);
542        }
543      }
544      else if (source_type.GetTypeClassification() == tTypeClassification::ARRAY)
545      {
546        size_t sources_element_offset = source_object.GetType().GetSize() / source_elements;
547        for (size_t i = 0; i < copy_elements; i++)
548        {
549          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * sources_element_offset, source_element_type);
550          tTypedPointer destination(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type);
551          operation.Continue(source, destination);
552        }
553      }
554      else if (copy_elements > 0)
555      {
556        tTypedConstPointer source_first = source_object.GetVectorElement(0);
557        tTypedPointer destination_first(static_cast<char*>(destination_object.GetRawDataPointer()), destination_element_type);
558        operation.Continue(source_first, destination_first);
559        if (copy_elements > 1)
560        {
561          tTypedConstPointer source_next = source_object.GetVectorElement(1);
562          tTypedPointer destination_second(static_cast<char*>(destination_object.GetRawDataPointer()) + destination_element_offset, destination_element_type);
563          operation.Continue(source_next, destination_second);
564          size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
565          for (size_t i = 2; i < copy_elements; i++)
566          {
567            source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, source_element_type);
568            tTypedPointer destination_next(static_cast<char*>(destination_object.GetRawDataPointer()) + i * destination_element_offset, destination_element_type);
569            operation.Continue(source_next, destination_next);
570          }
571        }
572      }
573
574      if (fill_elements)
575      {
576        if (destination_element_type.GetTypeTraits() & trait_flags::cIS_DEFAULT_CONSTRUCTION_ZERO_MEMORY)
577        {
578          memset(static_cast<char*>(destination_object.GetRawDataPointer()) + copy_elements * destination_element_offset, 0, fill_elements * destination_element_offset);
579        }
580        else
581        {
582          for (size_t i = 0; i < fill_elements; i++)
583          {
584            destination_element_type.EmplaceInstance(static_cast<char*>(destination_object.GetRawDataPointer()) + (copy_elements + i) * destination_element_offset);
585          }
586        }
587      }
588    }
589    else if (source_type.IsArray() && destination_type.IsListType())
590    {
591      size_t size = source_type.GetArraySize();
592      destination_object.ResizeVector(size);
593      if (size)
594      {
595        size_t source_element_offset = source_type.GetSize() / size;
596        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type);
597
598        if (destination_type == cBOOL_VECTOR_TYPE)
599        {
600          bool wrapped_bool = false;
601          tTypedPointer temp_destination_pointer(&wrapped_bool);
602          std::vector<bool>& destination = *destination_object.Get<std::vector<bool>>();
603
604          operation.Continue(source, temp_destination_pointer);
605          destination[0] = wrapped_bool;
606          if (size > 1)
607          {
608            tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
609            operation.Continue(source, temp_destination_pointer);
610            destination[1] = wrapped_bool;
611            for (size_t i = 2; i < size; i++)
612            {
613              tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
614              operation.Continue(source, temp_destination_pointer);
615              destination[i] = wrapped_bool;
616            }
617          }
618        }
619        else
620        {
621          tTypedPointer destination_first = destination_object.GetVectorElement(0);
622          operation.Continue(source, destination_first);
623          if (size > 1)
624          {
625            tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
626            tTypedPointer destination_next = destination_object.GetVectorElement(1);
627            operation.Continue(source, destination_next);
628            size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
629            for (size_t i = 2; i < size; i++)
630            {
631              tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
632              destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_element_type);
633              operation.Continue(source, destination_next);
634            }
635          }
636        }
637      }
638    }
639    else
640    {
641      throw std::runtime_error("Unsupported types for 'For Each' Operation");
642    }
643  }
644
645  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
646  {
647    throw std::logic_error("Not supported as single or second operation");
648  }
649
650  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
651  {
652    custom_data.ComputationTypes()[0] = conversion_option.source_type;
653    while (!(custom_data.ComputationTypes()[0].IsListType() || custom_data.ComputationTypes()[0].IsArray()))
654    {
655      custom_data.ComputationTypes()[0] = GetUnderlyingTypeOperationsAreInheritedFrom(custom_data.ComputationTypes()[0]);
656      if (!custom_data.ComputationTypes()[0])
657      {
658        throw std::runtime_error("Source type must be list or array");
659      }
660    }
661  }
662
663} cFOR_EACH;
664
665class tArrayToVector : public tRegisteredConversionOperation
666{
667public:
668  tArrayToVector() : tRegisteredConversionOperation(util::tManagedConstCharPointer("ToVector", false), tUnderlyingType(tSupportedTypeFilter::ARRAY_TO_VECTOR), tSupportedTypeFilter::ARRAY_TO_VECTOR)
669  {}
670
671  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
672  {
673    tType check_type = source_type;
674    while (check_type)
675    {
676      if (check_type.IsArray() && destination_type.IsListType() && check_type.GetElementType() == destination_type.GetElementType())
677      {
678        return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
679      }
680      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
681    }
682    return tConversionOption();
683  }
684
685  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
686  {
687    tType inter_type = operation.compiled_operation.IntermediateType();
688    char intermediate_memory[inter_type.GetSize(true)];
689    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
690    FinalConversionFunction(source_object, *intermediate_object, operation);
691    operation.Continue(*intermediate_object, destination_object);
692  }
693
694  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
695  {
696    const tType& source_type = operation.GetCustomData().ComputationTypes()[0];
697    const tType source_element_type = source_type.GetElementType();
698    size_t size = source_type.GetArraySize();
699    destination_object.ResizeVector(size);
700    if (size)
701    {
702      size_t source_element_offset = source_type.GetSize() / size;
703      tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()), source_element_type);
704      tTypedPointer destination_first = destination_object.GetVectorElement(0);
705      destination_first.DeepCopyFrom(source);
706      if (size > 1)
707      {
708        tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + source_element_offset, source_element_type);
709        tTypedPointer destination_next = destination_object.GetVectorElement(1);
710        destination_next.DeepCopyFrom(source);
711        size_t offset_destination = static_cast<const char*>(destination_next.GetRawDataPointer()) - static_cast<const char*>(destination_first.GetRawDataPointer());
712        for (size_t i = 2; i < size; i++)
713        {
714          tTypedConstPointer source(static_cast<const char*>(source_object.GetRawDataPointer()) + i * source_element_offset, source_element_type);
715          destination_next = tTypedPointer(static_cast<char*>(destination_next.GetRawDataPointer()) + offset_destination, destination_next.GetType());
716          destination_next.DeepCopyFrom(source);
717        }
718      }
719    }
720  }
721
722  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
723  {
724    custom_data.ComputationTypes()[0] = conversion_option.source_type;
725    while (!custom_data.ComputationTypes()[0].IsArray())
726    {
727      custom_data.ComputationTypes()[0] = GetUnderlyingTypeOperationsAreInheritedFrom(custom_data.ComputationTypes()[0]);
728      if (!custom_data.ComputationTypes()[0])
729      {
730        throw std::runtime_error("Source type must be array");
731      }
732    }
733  }
734} cARRAY_TO_VECTOR;
735
736class tGetTupleElement : public tRegisteredConversionOperation
737{
738public:
739  tGetTupleElement() : tRegisteredConversionOperation(util::tManagedConstCharPointer("get", false), tUnderlyingType(tSupportedTypeFilter::GET_TUPLE_ELEMENT), tSupportedTypeFilter::GET_TUPLE_ELEMENT, nullptr, tParameterDefinition("Index", tDataType<unsigned int>(), true))
740  {}
741
742  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
743  {
744    unsigned int index = 0;
745    if (parameter && parameter->GetType() == tDataType<std::string>())
746    {
747      index = serialization::Deserialize<unsigned int>(parameter->GetData<std::string>());
748    }
749    else if (parameter)
750    {
751      assert(parameter->GetType() == tDataType<unsigned int>());
752      index = parameter->GetData<unsigned int>();
753    }
754
755    tType check_type = source_type;
756    while (check_type)
757    {
758      auto tuple_types = check_type.GetTupleTypes();
759      if (index < tuple_types.second && destination_type == tType(tuple_types.first[index].type_info))
760      {
761        return tConversionOption(source_type, destination_type, tuple_types.first[index].offset);
762      }
763      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
764    }
765
766    return tConversionOption();
767  }
768} cGET_TUPLE_ELEMENT;
769
770class tWrapByteVectorOperation : public tRegisteredConversionOperation
771{
772public:
773  tWrapByteVectorOperation() : tRegisteredConversionOperation(util::tManagedConstCharPointer("Wrap", false), tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), &cCONVERSION_OPTION)
774  {}
775
776  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
777  {
778    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>();
779    if (vector.size())
780    {
781      const rrlib::serialization::tMemoryBuffer buffer(const_cast<uint8_t*>(&vector[0]), vector.size());
782      operation.Continue(tTypedConstPointer(&buffer), destination_object);
783    }
784    else
785    {
786      const rrlib::serialization::tMemoryBuffer buffer(0);
787      operation.Continue(tTypedConstPointer(&buffer), destination_object);
788    }
789  }
790
791  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
792  {
793    rrlib::serialization::tMemoryBuffer& buffer = *destination_object.Get<rrlib::serialization::tMemoryBuffer>();
794    const std::vector<uint8_t>& vector = *source_object.Get<std::vector<uint8_t>>();
795    buffer = rrlib::serialization::tMemoryBuffer(const_cast<uint8_t*>(&vector[0]), vector.size());
796    //const rrlib::serialization::tMemoryBuffer temp_buffer(const_cast<uint8_t*>(&vector[0]), vector.size());
797    //buffer.CopyFrom(temp_buffer);
798  }
799
800  static constexpr tConversionOption cCONVERSION_OPTION = tConversionOption(tDataType<std::vector<uint8_t>>(), tDataType<rrlib::serialization::tMemoryBuffer>(), true, &FirstConversionFunction, &FinalConversionFunction);
801} cWRAP_BYTE_VECTOR;
802
803constexpr tConversionOption tWrapByteVectorOperation::cCONVERSION_OPTION;
804
805class tListSize : public tRegisteredConversionOperation
806{
807public:
808  tListSize() : tRegisteredConversionOperation(util::tManagedConstCharPointer("size()", false), tUnderlyingType(tSupportedTypeFilter::LISTS), tDataType<size_t>())
809  {}
810
811  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
812  {
813    tType check_type = source_type;
814    while (check_type)
815    {
816      if (check_type.IsListType() && destination_type == tDataType<size_t>())
817      {
818        return tConversionOption(source_type, destination_type, false, &FirstConversionFunction, &FinalConversionFunction);
819      }
820      check_type = GetUnderlyingTypeOperationsAreInheritedFrom(check_type);
821    }
822    return tConversionOption();
823  }
824
825  static void FirstConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
826  {
827    size_t size = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]).GetVectorSize();
828    operation.Continue(tTypedConstPointer(&size), destination_object);
829  }
830
831  static void FinalConversionFunction(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
832  {
833    (*destination_object.Get<size_t>()) = tTypedConstPointer(source_object.GetRawDataPointer(), operation.GetCustomData().ComputationTypes()[0]).GetVectorSize();
834  }
835
836  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
837  {
838    custom_data.ComputationTypes()[0] = conversion_option.source_type;
839    while (!custom_data.ComputationTypes()[0].IsListType())
840    {
841      custom_data.ComputationTypes()[0] = GetUnderlyingTypeOperationsAreInheritedFrom(custom_data.ComputationTypes()[0]);
842      if (!custom_data.ComputationTypes()[0])
843      {
844        throw std::runtime_error("Source type must be list");
845      }
846    }
847  }
848} cLIST_SIZE;
849
850void StringToVectorConversionFunction(const std::string& source, std::vector<char>& destination)
851{
852  destination = std::vector<char>(source.begin(), source.end());
853}
854
855void VectorToStringConversionFunction(const std::vector<char>& source, std::string& destination)
856{
857  destination = std::string(source.begin(), source.end());
858}
859
860const tVoidFunctionConversionOperation<std::string, std::vector<char>, decltype(&StringToVectorConversionFunction), &StringToVectorConversionFunction> cSTRING_TO_VECTOR("ToVector");
861const tVoidFunctionConversionOperation<std::vector<char>, std::string, decltype(&VectorToStringConversionFunction), &VectorToStringConversionFunction> cVECTOR_TO_STRING("MakeString");
862
863class tAdjustLength : public tRegisteredConversionOperation
864{
865public:
866  tAdjustLength() : tRegisteredConversionOperation(util::tManagedConstCharPointer("AdjustLength", false), tUnderlyingType(tSupportedTypeFilter::ADJUST_LENGTH), tUnderlyingType(tSupportedTypeFilter::ADJUST_LENGTH))
867  {}
868
869  static tType GetSupportedType(const tType& type, bool source_type)
870  {
871    return (!type) ? tType() : ((type.IsArray() || (source_type && type.IsListType())) ? type : GetSupportedType(GetUnderlyingTypeOperationsAreInheritedFrom(type), source_type));
872  }
873
874  virtual tConversionOption GetConversionOption(const tType& source_type, const tType& destination_type, const tGenericObject* parameter) const override
875  {
876    tType supported_source_type = GetSupportedType(source_type, true);
877    tType supported_destination_type = GetSupportedType(destination_type, true);
878    if (supported_source_type && supported_destination_type && supported_source_type.GetElementType() == supported_destination_type.GetElementType())
879    {
880      const auto cQUICK_FLAGS = trait_flags::cIS_DEFAULT_CONSTRUCTION_ZERO_MEMORY | trait_flags::cSUPPORTS_BITWISE_COPY;
881      bool quick = (supported_source_type.GetElementType().GetTypeTraits() & cQUICK_FLAGS) == cQUICK_FLAGS;
882      assert(supported_destination_type.IsArray());
883      if (supported_source_type.IsArray() && quick)
884      {
885        if (supported_destination_type.GetSize() > supported_source_type.GetSize())
886        {
887          return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionMemset<&FinalConversionFunctionArrayMemcpy<true>>, &FinalConversionFunctionArrayMemcpy<true>);
888        }
889        else
890        {
891          return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionMemset<&FinalConversionFunctionArrayMemcpy<false>>, &FinalConversionFunctionArrayMemcpy<false>);
892        }
893      }
894      else if (supported_source_type == tDataType<std::vector<bool>>())
895      {
896        return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionMemset<&FinalConversionFunctionBoolVector>, &FinalConversionFunctionBoolVector);
897      }
898      else if (supported_source_type.IsArray())
899      {
900        return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionStandard<&FinalConversionFunctionArray>, &FinalConversionFunctionArray);
901      }
902
903      assert(supported_source_type.IsListType());
904      if (quick)
905      {
906        return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionMemset<&FinalConversionFunctionVector<true>>, &FinalConversionFunctionVector<true>);
907      }
908      return tConversionOption(source_type, destination_type, false, &FirstConversionFunctionStandard<&FinalConversionFunctionVector<false>>, &FinalConversionFunctionVector<false>);
909    }
910    return tConversionOption();
911  }
912
913  template <tConversionOption::tConversionFunction Tfinal_conversion>
914  static void FirstConversionFunctionMemset(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
915  {
916    tType inter_type = operation.compiled_operation.IntermediateType();
917    char intermediate_memory[inter_type.GetSize()];
918    memset(intermediate_memory, 0, sizeof(intermediate_memory));
919    tTypedPointer intermediate_object(intermediate_memory, inter_type);
920    (*Tfinal_conversion)(source_object, intermediate_object, operation);
921    operation.Continue(intermediate_object, destination_object);
922  }
923
924  template <tConversionOption::tConversionFunction Tfinal_conversion>
925  static void FirstConversionFunctionStandard(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
926  {
927    tType inter_type = operation.compiled_operation.IntermediateType();
928    char intermediate_memory[inter_type.GetSize(true)];
929    auto intermediate_object = inter_type.EmplaceGenericObject(intermediate_memory);
930    (*Tfinal_conversion)(source_object, *intermediate_object, operation);
931    operation.Continue(*intermediate_object, destination_object);
932  }
933
934  template <bool Tdestination_larger>
935  static void FinalConversionFunctionArrayMemcpy(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
936  {
937    if (Tdestination_larger)
938    {
939      size_t destination_size = destination_object.GetType().GetSize();
940      size_t copy_size = std::min(source_object.GetType().GetSize(), destination_size);
941      size_t fill_size = destination_size - source_object.GetType().GetSize();
942      memcpy(destination_object.GetRawDataPointer(), source_object.GetRawDataPointer(), copy_size);
943      memset(static_cast<char*>(destination_object.GetRawDataPointer()) + copy_size, 0, fill_size);
944    }
945    else
946    {
947      memcpy(destination_object.GetRawDataPointer(), source_object.GetRawDataPointer(), destination_object.GetType().GetSize());
948    }
949  }
950
951  static void FinalConversionFunctionArray(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
952  {
953    auto& custom_data = operation.GetCustomData();
954    const tType source_type = custom_data.ComputationTypes()[0];
955    const tType destination_type = custom_data.ComputationTypes()[1];
956    const tType element_type = source_type.GetElementType();
957    size_t element_size = element_type.GetSize();
958    bool destination_larger = destination_type > source_type;
959    size_t copy_size = std::min(source_type.GetArraySize(), destination_type.GetArraySize());
960
961    for (size_t i = 0; i < copy_size; i++)
962    {
963      tTypedConstPointer source_element(static_cast<const char*>(source_object.GetRawDataPointer()) + i * element_size, element_type);
964      tTypedPointer destination_element(static_cast<char*>(destination_object.GetRawDataPointer()) + i * element_size, element_type);
965      destination_element.DeepCopyFrom(source_element);
966    }
967
968    if (destination_larger)
969    {
970      for (size_t i = copy_size; i < destination_type.GetArraySize(); i++)
971      {
972        element_type.EmplaceInstance(static_cast<char*>(destination_object.GetRawDataPointer()) + i * element_size);
973      }
974    }
975  }
976
977  static void FinalConversionFunctionBoolVector(const tTypedConstPointer& source_object, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
978  {
979    const std::vector<bool>* source = source_object.GetUnchecked<std::vector<bool>>();
980    const tType destination_type = operation.GetCustomData().ComputationTypes()[1];
981    size_t destination_elements = destination_type.GetArraySize();
982
983    size_t copy_elements = std::min(source->size(), destination_elements);
984    size_t fill_elements = destination_elements - copy_elements;
985
986    for (size_t i = 0; i < copy_elements; i++)
987    {
988      *(static_cast<bool*>(destination_object.GetRawDataPointer()) + i) = (*source)[i];
989    }
990    memset(static_cast<bool*>(destination_object.GetRawDataPointer()) + copy_elements, 0, fill_elements);
991  }
992
993  template <bool Tmemcpy>
994  static void FinalConversionFunctionVector(const tTypedConstPointer& source_object_original, const tTypedPointer& destination_object, const tCurrentConversionOperation& operation)
995  {
996    auto& custom_data = operation.GetCustomData();
997    const tType destination_type = custom_data.ComputationTypes()[1];
998    const tType element_type = destination_type.GetElementType();
999    tTypedConstPointer source_object(source_object_original.GetRawDataPointer(), custom_data.ComputationTypes()[0]);
1000
1001    size_t copy_elements = std::min(source_object.GetVectorSize(), destination_type.GetArraySize());
1002    size_t fill_elements = destination_type.GetArraySize() - copy_elements;
1003
1004    if (copy_elements > 0)
1005    {
1006      tTypedConstPointer source_first = source_object.GetVectorElement(0);
1007      if (Tmemcpy)
1008      {
1009        memcpy(destination_object.GetRawDataPointer(), source_first.GetRawDataPointer(), element_type.GetSize());
1010      }
1011      else
1012      {
1013        tTypedPointer destination_element(static_cast<char*>(destination_object.GetRawDataPointer()), element_type);
1014        destination_element.DeepCopyFrom(source_first);
1015      }
1016
1017      if (copy_elements > 1)
1018      {
1019        tTypedConstPointer source_next = source_object.GetVectorElement(1);
1020        if (Tmemcpy)
1021        {
1022          memcpy(static_cast<char*>(destination_object.GetRawDataPointer()) + element_type.GetSize(), source_next.GetRawDataPointer(), element_type.GetSize());
1023        }
1024        else
1025        {
1026          tTypedPointer destination_element(static_cast<char*>(destination_object.GetRawDataPointer()) + element_type.GetSize(), element_type);
1027          destination_element.DeepCopyFrom(source_next);
1028        }
1029        size_t offset_source = static_cast<const char*>(source_next.GetRawDataPointer()) - static_cast<const char*>(source_first.GetRawDataPointer());
1030        for (size_t i = 2; i < copy_elements; i++)
1031        {
1032          source_next = tTypedConstPointer(static_cast<const char*>(source_next.GetRawDataPointer()) + offset_source, element_type);
1033          if (Tmemcpy)
1034          {
1035            memcpy(static_cast<char*>(destination_object.GetRawDataPointer()) + i * element_type.GetSize(), source_next.GetRawDataPointer(), element_type.GetSize());
1036          }
1037          else
1038          {
1039            tTypedPointer destination_element(static_cast<char*>(destination_object.GetRawDataPointer()) + i * element_type.GetSize(), element_type);
1040            destination_element.DeepCopyFrom(source_next);
1041          }
1042        }
1043      }
1044    }
1045
1046    if (fill_elements)
1047    {
1048      if (element_type.GetTypeTraits() & trait_flags::cIS_DEFAULT_CONSTRUCTION_ZERO_MEMORY)
1049      {
1050        size_t offset = copy_elements * element_type.GetSize();
1051        memset(static_cast<char*>(destination_object.GetRawDataPointer()) + offset, 0, destination_type.GetSize() - offset);
1052      }
1053      else
1054      {
1055        for (size_t i = 0; i < fill_elements; i++)
1056        {
1057          element_type.EmplaceInstance(static_cast<char*>(destination_object.GetRawDataPointer()) + (copy_elements + i) * element_type.GetSize());
1058        }
1059      }
1060    }
1061  }
1062
1063  virtual void OnCompile(const tConversionOption& conversion_option, tCustomOperationData& custom_data) const override
1064  {
1065    custom_data.ComputationTypes()[0] = GetSupportedType(conversion_option.source_type, true);
1066    custom_data.ComputationTypes()[1] = GetSupportedType(conversion_option.destination_type, true);
1067  }
1068
1069} cADJUST_LENGTH;
1070
1071}
1072
1073const tRegisteredConversionOperation& cTO_STRING_OPERATION = cTO_STRING;
1074const tRegisteredConversionOperation& cSTRING_DESERIALIZATION_OPERATION = cSTRING_DESERIALIZATION;
1075const tRegisteredConversionOperation& cBINARY_SERIALIZATION_OPERATION = cBINARY_SERIALIZATION;
1076const tRegisteredConversionOperation& cBINARY_DESERIALIZATION_OPERATION = cBINARY_DESERIALIZATION;
1077
1078const tRegisteredConversionOperation& cGET_LIST_ELEMENT_OPERATION = cGET_LIST_ELEMENT;
1079const tRegisteredConversionOperation& cFOR_EACH_OPERATION = cFOR_EACH;
1080const tRegisteredConversionOperation& cARRAY_TO_VECTOR_OPERATION = cARRAY_TO_VECTOR;
1081const tRegisteredConversionOperation& cGET_TUPLE_ELEMENT_OPERATION = cGET_TUPLE_ELEMENT;
1082
1083const tRegisteredConversionOperation& cWRAP_BYTE_VECTOR_OPERATION = cWRAP_BYTE_VECTOR;
1084const tRegisteredConversionOperation& cLIST_SIZE_OPERATION = cLIST_SIZE;
1085const tRegisteredConversionOperation& cSTRING_TO_VECTOR_OPERATION = cSTRING_TO_VECTOR;
1086const tRegisteredConversionOperation& cMAKE_STRING_OPERATION = cVECTOR_TO_STRING;
1087const tRegisteredConversionOperation& cADJUST_LENGTH_OPERATION = cADJUST_LENGTH;
1088
1089
1090//----------------------------------------------------------------------
1091// End of namespace declaration
1092//----------------------------------------------------------------------
1093}
1094}
1095}
Note: See TracBrowser for help on using the repository browser.