texttransformer.jpg

Delphi's class "TDictionary" is defined in the unit System.Generics.Collections. It is relatively complex and it uses much parts of the RTL. The correctness of the translation of code in which this class is used is guaranteed by a unit test which is derived from an Embarcadero example.

Generics_Collections_TDictionary

As for all test cases, the output operations have been replaced by boolean expressions which are checked at the execution of the test.
The translation with DelphiXE2Cpp11 doesn't require any further manual post-processing and is shown below. A couple of explanations follow.


#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

Though the C++ version of TDictionary has the same interfaces as the Delphi version, it isn' tadirect translation of the Delphi code. To guarantee a smooth integration of TDictionary into other C++ code, the class is derived from std::unordered_map. Therefore class doesn't only dispose the Delphi enumerators but also of C++ iterators. The latter are used implecitely also at the range based for-loop:


for Key in Dictionary.Keys do
->

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

The C++ translation from BobJenkinsHash in System.Generics.Defaults is used as hash function for the unordered map.


   deutsch Deutsch

 

 
Latest News
02/07/22
Delphi2Cpp: Delphi 10.3 inline variables [more...]

09/09/21
Delphi2CB: has been relased [more...]



"Thanks for your great work, really appreciate the work you have done on zlib and compiling ... test case."


Mattewada, Udayabhaskar
Nokia India 02/01/2021




[from case study...]

"A masterpiece -- Delphi2Cpp has exceeded all my expectations by far."


Tony Hürlimann
virtual-optima 08/20/2011



"First off, I have to say WOW! Delphi2Cpp is doing a *fantastic* job!"


Daniel Flower
linkrealms 01/15/2011


 
This website is generated from plain text with [Minimal Website ]

Minimal Website
Minimal Website is made with TextTransformer

TextTransformer
TextTransformer is made with Borland CBuilder

  borland