#pragma once
#include <stdio.h>
namespace
{
template
<
typename
>
struct
;
enum
class
{
,
,
,
,
,
};
#define PRINT_TYPE(...) \
do{ \
TypePrinter<__VA_ARGS__>::PrintPrefix(TypeSource::TopLevel); \
TypePrinter<__VA_ARGS__>::PrintPostfix(TypeSource::TopLevel); \
printf("\n"); \
}while(false) \
template
<
typename
>
struct
{
static
void
(
)
{
(
::Name);
if
(
==
::
)
(
" "
);
}
static
void
(
)
{
}
};
#define MAKE_PRIMITIVE_TYPE(NAME) \
template<> \
struct TypePrinter<NAME> : PrimitiveTypePrinter<TypePrinter<NAME>> \
{ \
static const char* const Name; \
}; \
const char* const TypePrinter<NAME>::Name = #NAME \
MAKE_PRIMITIVE_TYPE(bool);
template
<>
struct
<
bool
> :
<
<
bool
>> {
static
const
char
*
const
; };
const
char
*
const
<
bool
>::
=
"bool"
;
MAKE_PRIMITIVE_TYPE(char);
template
<>
struct
<
char
> :
<
<
char
>> {
static
const
char
*
const
; };
const
char
*
const
<
char
>::
=
"char"
;
MAKE_PRIMITIVE_TYPE(int);
template
<>
struct
<
int
> :
<
<
int
>> {
static
const
char
*
const
; };
const
char
*
const
<
int
>::
=
"int"
;
MAKE_PRIMITIVE_TYPE(float);
template
<>
struct
<
float
> :
<
<
float
>> {
static
const
char
*
const
; };
const
char
*
const
<
float
>::
=
"float"
;
MAKE_PRIMITIVE_TYPE(double);
template
<>
struct
<
double
> :
<
<
double
>> {
static
const
char
*
const
; };
const
char
*
const
<
double
>::
=
"double"
;
#undef MAKE_PRIMITIVE_TYPE
template
<
typename
,
typename
>
struct
{
static
void
(
)
{
<
>::
(
::
);
(
::Reference);
}
static
void
(
)
{
<
>::
(
::
);
}
};
#define MAKE_REFERENCE_TYPE(REFERENCE) \
template<typename T> \
struct TypePrinter<T REFERENCE> : ReferenceTypePrinter<TypePrinter<T REFERENCE>, T> \
{ \
static const char* const Reference; \
}; \
template<typename T> \
const char* const TypePrinter<T REFERENCE>::Reference = #REFERENCE \
MAKE_REFERENCE_TYPE(*);
template
<
typename
>
struct
<
*> :
<
<
*>,
> {
static
const
char
*
const
; };
template
<
typename
>
const
char
*
const
<
*>::
=
"*"
;
MAKE_REFERENCE_TYPE(&);
template
<
typename
>
struct
<
&> :
<
<
&>,
> {
static
const
char
*
const
; };
template
<
typename
>
const
char
*
const
<
&>::
=
"&"
;
MAKE_REFERENCE_TYPE(&&);
template
<
typename
>
struct
<
&&> :
<
<
&&>,
> {
static
const
char
*
const
; };
template
<
typename
>
const
char
*
const
<
&&>::
=
"&&"
;
#undef MAKE_REFERENCE_TYPE
template
<
typename
,
typename
>
struct
{
static
void
(
)
{
<
>::
(
::
);
(
::Qualifier);
}
static
void
(
)
{
<
>::
(
::
);
}
};
#define MAKE_QUALIFIED_TYPE(QUALIFIER) \
template<typename T> \
struct TypePrinter<T QUALIFIER> : QualifiedTypePrinter<TypePrinter<T QUALIFIER>, T> \
{ \
static const char* const Qualifier; \
}; \
template<typename T> \
const char* const TypePrinter<T QUALIFIER>::Qualifier = #QUALIFIER \
MAKE_QUALIFIED_TYPE(const);
template
<
typename
>
struct
<
const
> :
<
<
const
>,
> {
static
const
char
*
const
; };
template
<
typename
>
const
char
*
const
<
const
>::
=
"const"
;
MAKE_QUALIFIED_TYPE(volatile);
template
<
typename
>
struct
<
volatile
> :
<
<
volatile
>,
> {
static
const
char
*
const
; };
template
<
typename
>
const
char
*
const
<
volatile
>::
=
"volatile"
;
MAKE_QUALIFIED_TYPE(const volatile);
template
<
typename
>
struct
<
const
volatile
> :
<
<
const
volatile
>,
> {
static
const
char
*
const
; };
template
<
typename
>
const
char
*
const
<
const
volatile
>::
=
"const volatile"
;
#undef MAKE_QUALIFIED_TYPE
template
<
typename
,
int
>
struct
{
static
void
(
)
{
<
>::
(
::
);
if
(
!=
::
&&
!=
::
)
(
"("
);
}
static
void
(
)
{
if
(
!=
::
&&
!=
::
)
(
")"
);
(
"[%d]"
,
);
<
>::
(
::
);
}
};
#pragma warning (push)
#pragma warning (disable:
4003
)
#define MAKE_ARRAY_TYPE(QUALIFIER) \
template<typename T, int Size> \
struct TypePrinter<T QUALIFIER[Size]> : ArrayTypePrinter<T QUALIFIER, Size> \
{ \
} \
MAKE_ARRAY_TYPE();
template
<
typename
,
int
>
struct
<
[
]> :
<
,
> { };
#pragma warning (pop)
MAKE_ARRAY_TYPE(const);
template
<
typename
,
int
>
struct
<
const
[
]> :
<
const
,
> { };
MAKE_ARRAY_TYPE(volatile);
template
<
typename
,
int
>
struct
<
volatile
[
]> :
<
volatile
,
> { };
MAKE_ARRAY_TYPE(const volatile);
template
<
typename
,
int
>
struct
<
const
volatile
[
]> :
<
const
volatile
,
> { };
#undef MAKE_ARRAY_TYPE
template
<
typename
...
>
struct
;
template
<>
struct
<>
{
static
void
() {}
};
template
<
typename
>
struct
<
>
{
static
void
()
{
<
>::
(
::
);
<
>::
(
::
);
}
};
template
<
typename
,
typename
...
>
struct
<
,
...>
{
static
void
()
{
<
>::
(
::
);
<
>::
(
::
);
(
", "
);
<
...>::
();
}
};
template
<
typename
,
typename
...
>
struct
<
(
...)>
{
static
void
(
)
{
<
>::
(
::
);
if
(
!=
::
)
(
"("
);
}
static
void
(
)
{
if
(
!=
::
)
(
")"
);
(
"("
);
<
...>::
();
(
")"
);
<
>::
(
::
);
}
};
}