#pragma once
#include <intrin.h>
#define EXPR_TYPES(F)\
F(NumberExpr)\
F(UnaryExpr)\
F(BinaryExpr)\
#define EXPR_ACCEPT_VISITOR void Accept(IExprVisitor* visitor) override
namespace
{
#define DEFINE_EXPR(TYPE) class TYPE;
#undef DEFINE_EXPR
class
{
public
:
virtual
() =
default
;
#define VISIT_EXPR(TYPE) virtual void Visit(TYPE* self) = 0;
EXPR_TYPES(VISIT_EXPR)
virtual
void
(
*
) =
0
;
virtual
void
(
*
) =
0
;
virtual
void
(
*
) =
0
;
#undef VISIT_EXPR
};
template
<
typename
>
class
{
private
:
*
=
nullptr
;
void
();
void
();
public
:
()
{
}
(
*
)
:reference(
)
{
();
}
(
const
<
>&
)
:reference(
.
)
{
();
}
(
<
>&&
)
:reference(
.
)
{
.
=
nullptr
;
}
()
{
();
}
&
(
const
&
)
{
if
(
this
== &
)
return
*
this
;
();
=
.
;
();
return
*
this
;
}
&
(
&&
)
{
if
(
this
== &
)
return
*
this
;
();
=
.
;
.
=
nullptr
;
return
*
this
;
}
*
()
const
{
return
;
}
};
template
<
typename
>
void
<
>::
()
{
if
(
)
{
(&
->counter);
}
}
template
<
typename
>
void
<
>::
()
{
if
(
)
{
if
(
(&
->counter) ==
0
)
{
delete
;
=
nullptr
;
}
}
}
class
{
private
:
friend
class
<
>;
volatile
long
=
0
;
public
:
using
=
<
>;
virtual
() =
default
;
virtual
void
(
*
) =
0
;
};
class
:
public
{
public
:
double
;
};
enum
class
{
,
};
class
:
public
{
public
:
;
::
;
};
enum
class
{
,
,
,
,
};
class
:
public
{
public
:
;
::
;
::
;
};
extern
void
(
const
::
&
);
extern
double
(
const
::
&
);
}