1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
|
#include <iostream>
class vec2
{
private:
template<int a, int b>
class swizzle
{
private:
vec2& ref;
public:
vec2& operator=( const vec2& other )
{
ref.v[0] = other.v[a];
ref.v[1] = other.v[b];
return ref;
}
vec2& get_ref() const
{
return ref;
}
swizzle( vec2& self ) : ref( self ) {}
};
public:
//this is done so that vec2 can be accessed like this:
//vec2 a;
//float b = a.x;
//or
//float b = a.v[0];
union
{
struct
{
float x;
float y;
};
struct
{
float v[2];
};
};
vec2& operator=( const swizzle<0, 1> other )
{
x = other.get_ref().x;
y = other.get_ref().y;
return *this;
}
vec2& operator=( const swizzle<1, 0> other )
{
x = other.get_ref().y;
y = other.get_ref().x;
return *this;
}
vec2& operator=( const swizzle<0, 0> other )
{
x = other.get_ref().x;
y = other.get_ref().x;
return *this;
}
vec2& operator=( const swizzle<1, 1> other )
{
x = other.get_ref().y;
y = other.get_ref().y;
return *this;
}
swizzle<0, 1> xy;
swizzle<1, 0> yx;
swizzle<0, 0> xx;
swizzle<1, 1> yy;
//constructor for cases like vec2(0, 1)
vec2( float a, float b ) : xy( swizzle<0, 1>( *this ) ), yx( swizzle<1, 0>( *this ) ), xx( swizzle<0, 0>( *this ) ), yy( swizzle<1, 1>( *this ) )
{
x = a;
y = b;
}
//constructor for cases like vec2(1) (this also provides implicit conversion between float and vec2
vec2( float a ) : xy( swizzle<0, 1>( *this ) ), yx( swizzle<1, 0>( *this ) ), xx( swizzle<0, 0>( *this ) ), yy( swizzle<1, 1>( *this ) )
{
x = a;
y = a;
}
//default constructor
vec2() : xy( swizzle<0, 1>( *this ) ), yx( swizzle<1, 0>( *this ) ), xx( swizzle<0, 0>( *this ) ), yy( swizzle<1, 1>( *this ) )
{
v[0] = 0;
v[1] = 0;
}
};
int main( int argc, char* args[] )
{
vec2 a( 3, 4 );
vec2 b( 1, 2 );
a.yx = b; // working :)
b = a.yx; // working
//Expected: 2 1
//Result: 2 1
std::cout << "A: \n";
std::cout << a.x << " ";
std::cout << a.y << "\n";
//Expected 1 2
//Result 1 2
std::cout << "\nB: \n";
std::cout << b.x << " ";
std::cout << b.y << "\n";
return 0;
}
| |