texttransformer.jpg

Delphi's TDictionary Klasse ist in der unit System.Generics.Collections definiert, ist relativ komplex und beruht auf einer großen Teilen restlichen RTL. Die Korrektheit der Übersetzung von Code, in dem diese Klasse verwendet wird, wird in einem Unit-Test sicher gestellt, der von einem Embarcadero Beispiel abgeleitet ist.

Generics_Collections_TDictionary

Die Ausgabeoperationen sind für den Test durch boolsche Ausdrücke ersetzt worden, deren Werte überprüft werden.
Die Übersetzung mit Delphi2Cpp 2.x bedarf dann keiner weiteren manuellen Nachbearbeung mehr und ist im folgenden wiedergegeben. Anschließend folgen dann ein paar Erläuterungen.


#include "System.Types.h"
#include "System.Sysutils.h"
#include "System.Math.h"
#include "System.Generics.Collections.h"
#include "d2c_sysiter.h"

using namespace std;
using namespace System;
using namespace System::Generics::Collections;
using namespace System::Math;
using namespace System::Sysutils;
using namespace System::Types;

namespace docu_tdictionary
{


class TCity : public TObject
{
public:
  typedef TObject inherited;  
  String Country;
  double Latitude;
  double Longitude;
  void InitMembers(){Latitude = 0.0; Longitude = 0.0;}
  TCity() {InitMembers();}
};
const double epsilon = 0.0000001;

bool TestDictionary1()
{
  bool result = false;
  TDictionary* Dictionary = nullptr;
  TCity* City = nullptr;
  TCity* Value = nullptr;
  String key;
  bool bTest = false;
  String s;
  result = true;
  /* Create the dictionary. */
  Dictionary = new TDictionary();
  City = new TCity();
  /* Add some key-value pairs to the dictionary. */
  City->Country = L"Romania";
  City->Latitude = 47.16;
  City->Longitude = 27.58;
  Dictionary->Add(L"Iasi", City);
  City = new TCity();
  City->Country = L"United Kingdom";
  City->Latitude = 51.5;
  City->Longitude = -0.17;
  Dictionary->Add(L"London", City);
  City = new TCity();
  City->Country = L"Argentina";
  /* Notice the wrong coordinates */
  City->Latitude = 0;
  City->Longitude = 0;
  Dictionary->Add(L"Buenos Aires", City);

  /* Display the current number of key-value entries. */
  result = result && (Dictionary->ReadPropertyCount() == 3);

  // Try looking up "Iasi".
  if(Dictionary->TryGetValue(L"Iasi", City) == true)
  {
    result = result && (City->Country == L"Romania");
  }
  else
  result = false;

  /* Remove the "Iasi" key from dictionary. */
  Dictionary->Remove(L"Iasi");

  /* Make sure the dictionary's capacity is set to the number of entries. */
  Dictionary->TrimExcess();

  /* Test if "Iasi" is a key in the dictionary. */
  if(Dictionary->containsKey(L"Iasi"))
    result = false;

  /* Test how (United Kingdom, 51.5, -0.17) is a value in the dictionary but
    ContainsValue returns False if passed a different instance of TCity with the
    same data, as different instances have different references. */
  if(Dictionary->containsKey(L"London"))
  {
    Dictionary->TryGetValue(L"London", City);
    if((City->Country == L"United Kingdom") && (CompareValue(City->Latitude, 51.5, epsilon) == EqualsValue) && (CompareValue(City->Longitude, -0.17, epsilon) == EqualsValue))
      result = result && (City->Country == L"United Kingdom");
    else
      result = false;
    City = new TCity();
    City->Country = L"United Kingdom";
    City->Latitude = 51.5;
    City->Longitude = -0.17;
    if(Dictionary->containsValue(City))
      result = false;
    delete City;
  }
  else
  result = false;

  /* Update the coordinates to the correct ones. */
  City = new TCity();
  City->Country = L"Argentina";
  City->Latitude = -34.6;
  City->Longitude = -58.45;
  Dictionary->AddOrSetValue(L"Buenos Aires", City);

  /* Generate the exception "Duplicates not allowed". */
  try
  {
    bTest = false;
    Dictionary->Add(L"Buenos Aires", City);
  }
  catch(Exception*)
  {
    bTest = true;
  }
  result = result && (bTest == true);
  bTest = false;
  /* Display all countries. */
  for(TCity* element_0 : *Dictionary->ReadPropertyValues())
  {
    Value = element_0;
    if(Value->Country == L"Argentina")
      bTest = true;
  }
  result = result && (bTest == true);
  bTest = false;
  /* Iterate through all keys in the dictionary and display their coordinates. */
  for(UnicodeString element_0 : *Dictionary->ReadPropertyKeys())
  {
    key = element_0;
    s = FloatToStrF(Dictionary->ReadPropertyItems(key)->Longitude, ffFixed, 4, 2);
    if(s == L"-58,45")
      bTest = true;
  }
  result = result && (bTest == true);

  /* Clear all entries in the dictionary. */
  Dictionary->Clear();

  /* There should be no entries at this point. */
  result = result && (Dictionary->ReadPropertyCount() == 0);

  /* Free the memory allocated for the dictionary. */
  delete Dictionary;
  delete City;
  return result;
}

}  // namespace docu_tdictionary



Die C++ Version von TDictionary verfügt zwar über die gleichen Schnittstellem wie die Delphi Version, ist aber keine direkte Übersetzung Delphi Codes. Um eine nahtlose Integration von TDictionary in anderen C++ Code zu gewährleisten ist die Klasse von std::unordered_map abgeleitet. Damit verfügt die Klasse nicht nur über die Delphi Enumeratoren, sondern auch über C++ typische Iteratoren. Letztere werden implizit auch bei der Bereichsbasieren For-Schleife verwendet:


for Key in Dictionary.Keys do
->

for(TCity* element_0 : *Dictionary->ReadPropertyValues())

Als Hash-Funktion wird die C++-Übersetzung von BobJenkinsHash aus System.Generics.Defaults verwendet.


   english english

 

 
Letzte Neuigkeiten
29.01.24
Aurora2Cpp: Delphi 7 Konverter [more...]

19.10.23
Delphi2Cpp 2.3: Konvertierung von DFM-Dateien [more...]



[aus Fallstudie...]

"Eine Meisterleistung -- Delphi2Cpp hat alle meine Erwartungen weit übertroffen."


Tony Hürlimann
virtual-optima 29.08.2011



"Ich muss mich nochmal für deinen Einsatz und die Qualität deiner Arbeit bedanken, das ist absolut überdurchschnittlich ..."


Gerald Ebner


 
Diese Homepage ist aus einfachen Texten mit [Minimal Website ]generiert.

Minimal Website
Minimal Website ist mit Hilfe des TextTransformers hergestellt.

TextTransformer
Der TextTransformer ist gemacht mit dem Borland CBuilder

  borland