def test_type_expr_to_cpp_simple_reference_to_const():
    expr = ref(const(X))
    assert type_expr_to_cpp_simple(expr) == 'X const  &'
def test_type_expr_to_cpp_simple_type_member_access_pointer():
    expr = pointer(type_member_access(X, 'some_type'))
    assert type_expr_to_cpp_simple(expr) == 'typename X::some_type*'
def test_type_expr_to_cpp_simple_member_access_as_arg_of_function_type():
    expr = fun(Y, [type_member_access(X, 'some_type')])
    assert type_expr_to_cpp_simple(expr) == 'Y (typename X::some_type)'
def test_type_expr_to_cpp_simple_type_member_access():
    expr = type_member_access(X, 'some_type')
    assert type_expr_to_cpp_simple(expr) == 'typename X::some_type'
def test_type_expr_to_cpp_simple_template_member_access():
    expr = tmp_instantiation(
        template_member_access(Y, 'some_type', num_args=2), [X1, X2])
    assert type_expr_to_cpp_simple(
        expr) == 'typename Y::template some_type<X1, X2>'
def test_type_expr_to_cpp_simple_template_instantiation_with_function_type():
    MyTemplate = template('MyTemplate', num_args=1)
    expr = tmp_instantiation(MyTemplate, [fun(X1, [X2])])
    assert type_expr_to_cpp_simple(expr) == 'MyTemplate<X1 (X2)>'
def test_type_expr_to_cpp_simple_template_instantiation_as_return_type_of_function_type(
):
    MyTemplate = template('MyTemplate', num_args=1)
    expr = fun(tmp_instantiation(MyTemplate, [X2]), [Y])
    assert type_expr_to_cpp_simple(expr) == 'MyTemplate<X2> (Y)'
def test_type_expr_to_cpp_simple_function_type_two_args():
    expr = fun(Y, [X1, X2])
    assert type_expr_to_cpp_simple(expr) == 'Y (X1, X2)'
def test_type_expr_to_cpp_simple_function_pointer():
    expr = pointer(fun(Y, [X1]))
    assert type_expr_to_cpp_simple(expr) == 'Y(*) (X1)'
def test_type_expr_to_cpp_simple_function_type_no_args():
    expr = fun(Y, [])
    assert type_expr_to_cpp_simple(expr) == 'Y ()'
def test_type_expr_to_cpp_simple_function_type_one_arg():
    expr = fun(Y, [X])
    assert type_expr_to_cpp_simple(expr) == 'Y (X)'
def test_type_expr_to_cpp_simple_const_array_of_const():
    expr = const(array(const(X)))
    assert type_expr_to_cpp_simple(expr) == 'X const [] const '
def test_type_expr_to_cpp_simple_const_array():
    expr = const(array(X))
    assert type_expr_to_cpp_simple(expr) == 'X[] const '
def test_type_expr_to_cpp_simple_const_rvalue_reference_to_const():
    expr = const(rref(const(X)))
    assert type_expr_to_cpp_simple(expr) == 'X const  && const '
def test_type_expr_to_cpp_simple_template_instantiation_no_args():
    MyTemplate = template('MyTemplate', num_args=0)
    expr = tmp_instantiation(MyTemplate, [])
    assert type_expr_to_cpp_simple(expr) == 'MyTemplate<>'
def test_type_expr_to_cpp_simple_const_function_type():
    expr = const(fun(Y, [X1]))
    assert type_expr_to_cpp_simple(expr) == 'Y( const ) (X1)'
def test_type_expr_to_cpp_simple_template_instantiation_one_arg():
    MyTemplate = template('MyTemplate', num_args=1)
    expr = tmp_instantiation(MyTemplate, [X])
    assert type_expr_to_cpp_simple(expr) == 'MyTemplate<X>'
def test_type_expr_to_cpp_simple_function_type_rvalue_reference():
    expr = rref(fun(Y, [X1]))
    assert type_expr_to_cpp_simple(expr) == 'Y( &&) (X1)'
def test_type_expr_to_cpp_simple_template_instantiation_as_arg_of_function_type(
):
    MyTemplate = template('MyTemplate', num_args=1)
    expr = fun(X1, [tmp_instantiation(MyTemplate, [X2])])
    assert type_expr_to_cpp_simple(expr) == 'X1 (MyTemplate<X2>)'
def test_type_expr_to_cpp_simple_function_type_array():
    expr = array(fun(Y, [X1]))
    assert type_expr_to_cpp_simple(expr) == 'Y([]) (X1)'
def test_type_expr_to_cpp_simple_template_instantiation_pointer():
    MyTemplate = template('MyTemplate', num_args=2)
    expr = pointer(tmp_instantiation(MyTemplate, [X1, X2]))
    assert type_expr_to_cpp_simple(expr) == 'MyTemplate<X1, X2>*'
def test_type_expr_to_cpp_simple_function_returning_function():
    expr = funptr(funptr(funptr(funptr(Y, [X1]), [X2]), [X3]), [X4])
    assert type_expr_to_cpp_simple(expr) == 'Y(*(*(*(*) (X4)) (X3)) (X2)) (X1)'
def test_type_expr_to_cpp_simple_type_member_access_nested():
    expr = type_member_access(type_member_access(X, 'some_type'), 'other_type')
    assert type_expr_to_cpp_simple(expr) == 'typename X::some_type::other_type'
def test_type_expr_to_cpp_simple_function_returning_const_function():
    expr = funptr(const(funptr(Y, [X1])), [X2])
    assert type_expr_to_cpp_simple(expr) == 'Y(* const (*) (X2)) (X1)'
def test_type_expr_to_cpp_simple_member_access_on_template():
    MyTemplate = template('MyTemplate', num_args=2)
    expr = type_member_access(tmp_instantiation(MyTemplate, [X1, X2]),
                              'some_type')
    assert type_expr_to_cpp_simple(
        expr) == 'typename MyTemplate<X1, X2>::some_type'
def test_type_expr_to_cpp_simple_function_with_function_arg():
    expr = funptr(X1, [funptr(X2, [funptr(X3, [funptr(X4, [Y])])])])
    assert type_expr_to_cpp_simple(expr) == 'X1(*) (X2(*) (X3(*) (X4(*) (Y))))'
def test_type_expr_to_cpp_simple_int_member_access():
    expr = int_member_access(X, 'some_number')
    assert type_expr_to_cpp_simple(expr) == 'X::some_number'
def test_type_expr_to_cpp_simple_function_with_const_function_arg():
    expr = funptr(X1, [const(funptr(X2, [Y]))])
    assert type_expr_to_cpp_simple(expr) == 'X1(*) (X2(* const ) (Y))'
def test_type_expr_to_cpp_simple_member_access_as_return_type_of_function_type(
):
    expr = fun(type_member_access(X, 'some_type'), [Y])
    assert type_expr_to_cpp_simple(expr) == 'typename X::some_type (Y)'
def test_type_expr_to_cpp_simple_const_reference():
    expr = const(ref(X))
    assert type_expr_to_cpp_simple(expr) == 'X & const '