// PERMUTE_ARGS:

import core.stdc.stdio;
import core.stdc.stdlib;

/*********************************************/

class Foo
{
    static uint flags;

    new(size_t sz, int x)
    {   void* p;

        printf("Foo.new(sz = %d, x = %d)\n", sz, x);
        assert(sz == Foo.classinfo.init.length);
        assert(x == 5);

        p = core.stdc.stdlib.malloc(sz);
        flags |= 4;
        return p;
    }

    this()
    {
        printf("this() %p\n", this);
        a = 36;
    }

    ~this()
    {
        printf("~this() %p\n", this);
        a = -5;
        flags |= 1;
    }

    delete(void* p)
    {
        printf("delete %p\n", p);
        free(p);
        flags |= 2;
    }

    int a = 3;
    int b = 4;
    int d = 56;
}

void test1()
{
    Foo f;

    f = new(5) Foo;
    assert(f.a == 36);
    assert(f.b == 4);
    assert(f.d == 56);
    assert(Foo.flags == 4);

    delete f;
    assert(Foo.flags == 7);
}


/*********************************************/

struct Foo2
{
    static uint flags;

    new(size_t sz, int x)
    {   void* p;

        printf("Foo2.new(sz = %d, x = %d)\n", sz, x);
        assert(sz == Foo2.sizeof);
        assert(x == 5);

        p = core.stdc.stdlib.malloc(sz);
        flags |= 4;
        return p;
    }

    delete(void *p)
    {
        printf("p = %p\n", p);
        flags |= 2;
        core.stdc.stdlib.free(p);
    }
}

void test2()
{
    Foo2 *f = new(5) Foo2();

    printf("f = %p\n", f);
    delete f;
    assert(Foo2.flags == 6);
}


/*********************************************/

int main()
{
    test1();
    test2();

    printf("Success\n");
    return 0;
}

