/+
REQUIRED_ARGS: -o- -HC
TEST_OUTPUT:
---
// Automatically generated by Digital Mars D Compiler

#pragma once

#include <assert.h>
#include <math.h>
#include <stddef.h>
#include <stdint.h>

extern int32_t foo();

extern int32_t* somePtr;

extern void insertedCast(double a = (double) foo());

extern void explicitCast(int32_t b = foo());

extern void requiredCast(void* ptr = (void*) foo());

extern void stcCast(const int32_t* const ci = (const int32_t* const) somePtr);

---
+/

extern (C++):

int foo() { return 0; }

__gshared int* somePtr;

void insertedCast(double a = foo()) {}

void explicitCast(int b = cast(int) foo()) {}

void requiredCast(void* ptr = cast(void*) foo()) {}

void stcCast(const int* ci = cast(immutable) somePtr) {}

/+
TEST_OUTPUT:
---
template <typename T>
extern T insertedTmpl(double a = static_cast<double>(foo()));

template <typename T>
extern T explicitTmpl(int32_t b = (int32_t) foo());

template <typename T>
extern T requiredTmpl(void* ptr = (void*) foo());

template <typename T>
extern T stcCastTmpl(int32_t* ci = (int32_t*) somePtr);

template <typename T>
extern T paramCastTmpl(int32_t* ci = (T) somePtr);
---
+/

T insertedTmpl(T)(double a = foo()) {}

T explicitTmpl(T)(int b = cast(int) foo()) {}

T requiredTmpl(T)(void* ptr = cast(void*) foo()) {}

T stcCastTmpl(T)(const int* ci = cast(immutable) somePtr) {}

T paramCastTmpl(T)(const int* ci = cast(T) somePtr) {}

/+
TEST_OUTPUT:
---

struct Data final
{
    static Data* pt;
    static int32_t* bar();
    Data()
    {
    }
};

extern void useData(bool a = !Data::pt, bool b = Data::bar() == nullptr, bool c = Data::bar() != nullptr);
---
+/

struct Data
{
    __gshared Data* pt;
    static int* bar() { return null; }
}

void useData(
    bool a = !Data.pt,
    bool b = Data.bar() is null,
    bool c = Data.bar() !is null
) {}
