-
Notifications
You must be signed in to change notification settings - Fork 7
Conversion samples
Loïc HAMOT edited this page May 28, 2016
·
7 revisions
// C++
class Widget {
Widget(Widget const&);
Widget& operator=(Widget const&);
Widget* parent_;
virtual void displayImpl() = 0;
virtual void onClickImpl(size_t x, size_t y) = 0;
public:
Widget(Widget* parent = nullptr): parent_(parent) {}
~Widget() = default;
void display() { displayImpl(); }
void onClick(size_t x, size_t y) { onClickImpl(x, y); }
};// D
class Widget
{
private:
Widget parent_;
protected:
abstract void displayImpl();
abstract void onClickImpl(size_t x, size_t y);
public:
this(Widget parent = null)
{
parent_ = parent;
}
final void display()
{
displayImpl();
}
final void onClick(size_t x, size_t y)
{
onClickImpl(x, y);
}
}- virtual keyword is removed
- = 0 become abstract
- No-virtual methods become final
- Constructor are renamed this
- private abstract methods are printed to protected
// C++
class ChildWidget : public Widget {
void displayImpl() override { printf("displayImpl\n"); }
void onClickImpl(size_t x, size_t y) { printf("onClickImpl %u %u\n", x, y); }
public:
ChildWidget(Widget* parent = nullptr) :Widget(parent) {}
};// D
class ChildWidget : Widget
{
protected:
override void displayImpl()
{
writef("displayImpl\n\0");
}
override void onClickImpl(size_t x, size_t y)
{
writef("onClickImpl %u %u\n\0", x, y);
}
public:
this(Widget parent = null)
{
super(parent);
}
}- Inheritance and access specifiers are removed
- override is added on all overriding methods
- Call super for construct the base type
- private override methods are printed to protected
// C++
int main(){
Widget* w = new ChildWidget();
w->display();
w->onClick(1, 2);
delete w;
}// D
int main()
{
Widget w = new ChildWidget(null);
w.display();
w.onClick(1, 2);
w = null;
}- Remove pointer to class
- assign null in place of delete
// C++
struct Rational // Stupidly simple rational struct
{
int num = 1;
int den = 1;
Rational(int num_, int den_ = 1) : num(num_), den(den_) {}
bool operator == (Rational const& rhs) {
return num == rhs.num && den == rhs.den;
}
bool operator != (Rational const& rhs) {
return !(*this == rhs);
}
bool operator < (Rational const& rhs) {
return num * rhs.den < rhs.num * den;
}
bool operator <= (Rational const& rhs) {
return *this < rhs || *this == rhs;
}
bool operator >= (Rational const& rhs) {
return !(*this < rhs);
}
bool operator > (Rational const& rhs) {
return !(*this <= rhs);
}
};
Rational& operator += (Rational& lhs, Rational const& rhs){
lhs.num = lhs.num * rhs.den + rhs.num * lhs.den;
lhs.den *= rhs.den;
return lhs;
}
Rational operator + (Rational const& lhs, Rational const& rhs){
Rational tmp = lhs;
tmp += rhs;
return tmp;
}
int operator * (int lhs, Rational const& rhs){
lhs *= rhs.num;
return lhs / rhs.den;
}// D
struct Rational
{
int num = 1;
int den = 1;
this(int num_, int den_ = 1)
{
num = num_;
den = den_;
}
bool opEquals(Rational rhs)
{
return num == rhs.num && den == rhs.den;
}
bool _opLess(Rational rhs)
{
return num * rhs.den < rhs.num * den;
}
ref Rational opOpAssign(string op: "+")(Rational rhs)
{
alias lhs = this;
lhs.num = lhs.num * rhs.den + rhs.num * lhs.den;
lhs.den *= rhs.den;
return lhs;
}
Rational opBinary(string op: "+")(Rational rhs)
{
alias lhs = this;
Rational tmp = lhs;
tmp += rhs;
return tmp;
}
int opBinaryRight(string op: "*")(int lhs)
{
alias rhs = this;
lhs *= rhs.num;
return lhs / rhs.den;
}
int opCmp(ref in Rational other)
{
return _opLess(other) ? -1: ((this == other)? 0: 1);
}
}- Constructor initializer list is printed to simple assignment operation
- Operators are renamed to the D operator name style
- Useless operators are prefixed by an underscore
- opCmp is create and use the old operator<, renamed _opLess, and opAssign
- Free operators are moved into the struct
- Free operator with Rational at the right are moved into the struct with the Right suffix, like opBinaryRight
// C++
template<typename T>
T max(T a, T b) {
return (a >= b)? a: b;
}// D
T max(T)(T a, T b)
{
return (a >= b)? a: b;
}// C++
template<typename T> void WhoAmI(T A);
template<> void WhoAmI<int>(int){
printf("I am int");
}
template<> void WhoAmI<double>(double) {
printf("I am double");
}// D
void WhoAmI(T)(T A);
void WhoAmI(T : int)(int var0)
{
writef("I am int\0");
}
void WhoAmI(T : double)(double var0)
{
writef("I am double\0");
}// C++
template<typename T> struct TmpClass;
template<> struct TmpClass<int>{
void WhoAmI() {
printf("I am a <int> template\n");
}
};
template<> struct TmpClass<double> {
void WhoAmI() {
printf("I am a <double> template\n");
}
};// D
struct TmpClass(T);
struct TmpClass(T : int)
{
void WhoAmI()
{
writef("I am a <int> template\n\0");
}
};
struct TmpClass(T : double)
{
void WhoAmI()
{
writef("I am a <double> template\n\0");
}
};
// C++
template<typename T, bool DoMax> class Max;
template<typename T> class Max<T, true> {
public:
static T get(T a, T b) {
return (a >= b) ? a : b; //get the max
}
};
template<typename T> class Max<T, false> {
public:
static T get(T a, T b) {
return (a < b) ? a : b; //get the min
}
};// D
class Max(T, bool DoMax);
class Max(T : T_, bool DoMax : 1, T_)
{
public:
static final T_ get(T_ a, T_ b)
{
return (a >= b)? a: b; //get the max
}
};
class Max(T : T_, bool DoMax : 0, T_)
{
public:
static final T_ get(T_ a, T_ b)
{
return (a < b)? a: b; //get the min
}
};// C++
int static_array[] = { 0, 1, 2, 3 };
assert(static_array[3] == 3);
for (auto i : static_array)
assert(i == static_array[i]);
for (int i = 0; i < sizeof(static_array) / sizeof(int); ++i)
assert(i == static_array[i]);// D
int[4] static_array = [0, 1, 2, 3,];
assert(static_array[3] == 3);
foreach( i; static_array)
assert(i == static_array[i]);
for(int i = 0; i < (static_array).sizeof / int.sizeof; ++i)
assert(i == static_array[i]);- Array initializer list is printed with Brackets
-
range-base for-loop are replaced by foreach.
- The auto keyword is not printed in foreach.
- assert is correctly converted
- sizeof is correctly converted
// C++
void check_array(int* arr, size_t size){
assert(arr[3] == 3);
}
int main(){
int* dynamic_array = new int[5];
dynamic_array[4] = 3;
check_array(dynamic_array + 1, 4);
delete[] dynamic_array;
}// D
void check_array(int[] arr, size_t size)
{
assert(arr[3] == 3);
}
int main()
{
int[] dynamic_array = new int[5];
dynamic_array[4] = 3;
check_array(dynamic_array[1..$], 4);
dynamic_array = null;
}- pointer + 1 is replaced by pointer[1..$]
- int* is replaced by int[]