#include <vector>
#include <utility>
#include <cstdio>
#include <cstdint>
#include <cstring>
#include <ctime>
enum class ShapeType
{
rectangle = 0,
circle = 1,
triangle = 2,
};
struct Shape
{
ShapeType type;
virtual float getarea() = 0;
};
struct Rectangle: Shape
{
float x;
float y;
virtual float getarea() override
{
return x * y;
}
};
struct Circle: Shape
{
float r;
virtual float getarea() override
{
return 6.2831853072f * r;
}
};
struct Triangle: Shape
{
float a;
float b;
float cosp;
virtual float getarea() override
{
return 0.5f * a * b * cosp;
}
};
union ShapeUnion
{
Rectangle rectangle;
Circle circle;
Triangle triangle;
ShapeUnion()
{
}
ShapeUnion( ShapeUnion&& other )
{
memcpy( this, &other, sizeof( ShapeUnion ) );
}
~ShapeUnion()
{
}
float getarea_virtual();
float getarea_switch();
};
float ShapeUnion::getarea_virtual()
{
Shape* ptr = ( Shape* )this;
return ptr->getarea();
}
float ShapeUnion::getarea_switch()
{
switch( ( ( Shape* )this )->type )
{
case ShapeType::rectangle:
return rectangle.getarea();
case ShapeType::circle:
return circle.getarea();
case ShapeType::triangle:
return triangle.getarea();
}
return 0;
}
std::vector< ShapeUnion > suv;
void fill_vector()
{
suv.resize( 0x1000000 );
for( auto& su: suv )
{
uint32_t n = uintptr_t( &su );
n = ( n << 13 ) ^ n;
n = n * ( n * n * 15731 + 789221 ) + 1376312589;
switch( n % 3 )
{
case 0:
new( &su )Rectangle();
su.rectangle.type = ShapeType::rectangle;
su.rectangle.x = n >> 16;
su.rectangle.y = n & 0xffff;
case 1:
new( &su )Circle();
su.circle.type = ShapeType::circle;
su.circle.r = n;
case 2:
new( &su )Triangle();
su.triangle.type = ShapeType::triangle;
su.triangle.a = n >> 20;
su.triangle.b = ( n >> 8 ) & 0xfff;
su.triangle.cosp = ( n & 0xff ) / 255.0f;
}
}
}
void test_virtual()
{
volatile float r;
for( auto& su: suv )
{
r = su.getarea_virtual();
}
( void )r;
}
void test_switch()
{
volatile float r;
for( auto& su: suv )
{
r = su.getarea_switch();
}
( void )r;
}
int main()
{
fill_vector();
clock_t c1 = clock();
for( int i = 0; i < 0x10; ++i )
{
test_virtual();
}
c1 = clock() - c1;
clock_t c2 = clock();
for( int i = 0; i < 0x10; ++i )
{
test_switch();
}
c2 = clock() - c2;
printf( "%li\n%li\n", c1, c2 );
return 0;
}