// Testing the virtual cast, as part of strict inheritance.

/* IMPORTANT: This test does not repersent the final feature set.
 * We are missing a number of important aspects such as:
 * + vtable type generation.
 * + vtable instance generation, that might use different resolution rules.
 * + Virtual syntax to force said generation on structures and traits.
 * + Trait references/pointers that do the virtual_table lookup.
 */

#include <stdlib>
#include <assert.h>

struct alpha_vtable {
	alpha_vtable const * const parent;
	char (*code)(void);
};

struct alpha {
	alpha_vtable const * virtual_table;
};

char ret_a(void) {
	return 'a';
}



struct beta_vtable {
	alpha_vtable const * const parent;
	char (*code)(void);
};

struct beta {
	beta_vtable const * virtual_table;
};

char ret_b(void) {
	return 'b';
}



struct gamma_vtable {
	beta_vtable const * const parent;
	char (*code)(void);
};

struct gamma {
	gamma_vtable const * virtual_table;
};

char ret_g(void) {
	return 'g';
}


extern "C" {
	alpha_vtable _alpha_vtable_instance = { 0, ret_a };
	beta_vtable _beta_vtable_instance = { &_alpha_vtable_instance, ret_b };
	gamma_vtable _gamma_vtable_instance = { &_beta_vtable_instance, ret_g };
}

int main (int argc, char * argv[]) {

	gamma * tri = malloc(); tri->virtual_table = &_gamma_vtable_instance;
	beta * mid = (virtual beta *)tri;
	assert( 'g' == mid->virtual_table->code() );

	alpha * top = malloc(); top->virtual_table = &_alpha_vtable_instance;
	mid = (virtual beta *)top;
	assert( ! mid );

	free(tri);
	free(top);
}
