[C++] properste manier om vector component te selecteren

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 14-09 18:19
In veel van mijn methods werk ik apart op de x, y of z component van vector achtige structs, waardoor ik met veel code duplicatie zou zitten, bvb:
CoolClass::processEveryX()
CoolClass::processEveryY()
CoolClass::processEveryZ()

Niet wat je wil dus, dus ik dacht dit met templates op te lossen om zo at compile time de juiste functies te krijgen.

Wat ik nu heb, en het ziet er naar uit dat het alleszins een oplossing is:

C++:
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
struct SelectX{
    template<class Vector>
    static auto select(Vector& vec) -> decltype(vec.x)& {
        return vec.x;
    }
};

// struct SelectY { ....

// enz ...

struct XVec3 {
    float x;
    float y;
};

template<class Selector, class Vector>
void selectTest(Vector& vec){
    auto& t = Selector::select(vec);
}


void test()
{
    XVec3 test;
    selectTest<SelectX>(test);
}


Nu is de vraag natuurlijk, is er een simpelere manier om zaken als deze te implementeren? Want met het groen achter mijn oren heb ik het gevoel dat ik misschien wel een oplossing heb, maar een die misschien veel beter kan.

edit: een vereiste is natuurlijk dat de compiler de Selector::select() kan wegwerken en ik dus zonder overhead aan VectorType.x kom ipv dat er nog een call tussenzit.

[ Voor 8% gewijzigd door Bob op 22-04-2010 11:04 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Pointer-to-members?

C++:
1
2
3
4
5
6
7
8
9
10
11
12
void test()
{
    float XVec3::*ptr;
    XVec3 a, b;

    ptr = &XVec3::x;
    a.*ptr = 34;
    b.*ptr = 22;

    ptr = &XVec3::y;
    a.*ptr = 1;
}


Een andere veelgebruikte oplossing is om gewoon een operator[] of operator() te definieren op je vector types, zodat je gewoon kunt indexeren.
edit: een vereiste is natuurlijk dat de compiler de Selector::select() kan wegwerken en ik dus zonder overhead aan VectorType.x kom ipv dat er nog een call tussenzit
Een fatsoenlijke compiler zal zo'n call gewoon wegwerken.

[ Voor 50% gewijzigd door .oisyn op 22-04-2010 11:20 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 14-09 18:19
Begrijp ik het juist als ik zeg dat zo'n pointer een offset is die dan kan gebruik worden om een member van een instance te verkrijgen? En dat die offset dan ook at compile time vast kan liggen? (ik zit hier met inner loop toestanden, dus het zal waarschijnlijk wel iets uitmaken)

Misschien ben ik te hard aan het doordraven, maar toch:
Stel ik gebruik een pointer-to-member. Dan ga ik waarschijnlijk op de volgende manier een functie gebruiken:
C++:
1
2
3
4
void doWithComponent(float param, float XVec3::* ptr) {
    // vector is elsewhere defined
    vector.*ptr += param;
}


Nu wordt het voor de compiler toch moeilijk om hier compile time optimalisaties uit te voeren, niet? Ofwel moet hij heel de boel inlinen, ofwel wordt ptr gewoon als parameter meegegeven en is er geen compile time optimalisatie. Ofwel ken ik niet genoeg van compilers. :)

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

gewoon zo, dat is echt verreweg het makkelijkste:

C++:
1
2
3
4
5
6
7
8
struct Vector {
   float data[3];
   float& operator[](size_t x) {return data[x];}
};

void process(const Vector& x, size_t i) {
   x[i];
}

[ Voor 20% gewijzigd door Zoijar op 22-04-2010 11:54 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het vervelende van die oplossing is dat je dan niet meer de afzonderlijke componenten via variabelen aan kunt spreken.

Ik doe zelf meestal zoiets:
C++:
1
2
3
4
5
struct Vector
{
    float x, y, z;
    float & operator[](int i) { return (&x)[i]; }
};

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
.oisyn schreef op donderdag 22 april 2010 @ 11:56:
Het vervelende van die oplossing is dat je dan niet meer de afzonderlijke componenten via variabelen aan kunt spreken.
Even een union er omheen gooien en dat probleem is verleden tijd :-).

Is het overigens, gezien de interface in de eerste post, niet handiger om zoiets te doen:

C++:
1
2
3
4
5
struct VectorList{
    float *x, *y, *z;
};

void CoolClass::processEvery(float *c);

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

PrisonerOfPain schreef op donderdag 22 april 2010 @ 12:12:
[...]


Even een union er omheen gooien en dat probleem is verleden tijd :-).
Behalve dat C++ geen anonymous structs toestaat.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

die (&x)[i] is ook niet 100% safe mbt alignment; compiler zou je 32 bit float members op 64 bit boundaries mogen alignen. Wat dat betreft neemt een float data[3] altijd 12 bytes in, maar kan een float x,y,z er zo maar 24 in nemen.

[ Voor 31% gewijzigd door Zoijar op 22-04-2010 12:21 ]


Acties:
  • 0 Henk 'm!

  • PrisonerOfPain
  • Registratie: Januari 2003
  • Laatst online: 26-05 17:08
.oisyn schreef op donderdag 22 april 2010 @ 12:15:
[...]

Behalve dat C++ geen anonymous structs toestaat.
Is dat een visual studio extension dan? Want dit compiled gewoon.

C++:
1
2
3
4
5
6
struct foo{
    union{
        struct { float x, y, z; };
        float data[3];
    };
};


Edit: Ja dus, maar zo te zien ondersteunen meer compilers dit (VC++, GCC en Intel).

[ Voor 10% gewijzigd door PrisonerOfPain op 22-04-2010 12:30 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar schreef op donderdag 22 april 2010 @ 12:20:
die (&x)[i] is ook niet 100% safe mbt alignment; compiler zou je 32 bit float members op 64 bit boundaries mogen alignen. Wat dat betreft neemt een float data\[3] altijd 12 bytes in, maar kan een float x,y,z er zo maar 24 in nemen.
Volgens mij is dat onjuist, heb je hier een bron van? Bij mij weten hebben x floats achter elkaar binnen hetzelfde public/protected/private blok altijd dezelfde memory layout als een array van x floats.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op donderdag 22 april 2010 @ 12:43:
Volgens mij is dat onjuist, heb je hier een bron van? Bij mij weten hebben x floats achter elkaar binnen hetzelfde public/protected/private blok altijd dezelfde memory layout als een array van x floats.
Ik twijfel ook nu...

Acties:
  • 0 Henk 'm!

Verwijderd

Kan je niet een method aan de class toevoegen die de bewerkingen voor je uitvoert?
Of anders zoals in je beginpost een
CoolClass::processEvery(property)
i.p.v. drie losse?

Acties:
  • 0 Henk 'm!

  • BoAC
  • Registratie: Februari 2003
  • Laatst online: 07:52

BoAC

Memento mori

.oisyn schreef op donderdag 22 april 2010 @ 12:43:
[...]

Volgens mij is dat onjuist, heb je hier een bron van? Bij mij weten hebben x floats achter elkaar binnen hetzelfde public/protected/private blok altijd dezelfde memory layout als een array van x floats.
public/protected private heeft daar toch zelfs geen invloed op?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Jawel, een compiler mag verschillende blokken herordenen. Overigens twijfel ik nu ook, en vrees ik dat Zoijar gelijk heeft - binnen hetzelfde blok heeft een member altijd een hoger adres dan het vorige, maar blokken kunnen wel interleaved worden.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

9.2.12 uit de oude draft:

-12- Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (class.access.spec). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (class.virtual) and virtual base classes (class.mi).

Overigens weigert VC9 ze anders dan op 32bits te alignen, zelfs met #pragma pack. Alleen met een expliciete declspec gaat het fout.

C++:
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
#include <iostream>

#pragma pack(16)
struct Vector {
//  __declspec(align(8)) 
        float x, y, z;
//  __declspec(align(8)) 
        float data[3];
};

int main() {
    Vector v;


    std::cout << "Offset x y z: " << 
        (char*)&v.x - (char*)&v << " " <<
        (char*)&v.y - (char*)&v << " " <<
        (char*)&v.z - (char*)&v << std::endl;

    std::cout << "Offset data: " << 
        (char*)&v.data[0] - (char*)&v << " " <<
        (char*)&v.data[1] - (char*)&v << " " <<
        (char*)&v.data[2] - (char*)&v << std::endl;

    return 0;
}

[ Voor 37% gewijzigd door Zoijar op 22-04-2010 13:16 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other
Maar dat geldt dan net zo goed voor arrays, want die requirement is daar ook op van toepassing.

[ Voor 7% gewijzigd door .oisyn op 22-04-2010 13:15 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Om de componenten aan te spreken met hun variabelenaam en een indexnotatie, vond ik dit wel een mooie oplossing ( lees ook het einde van het topic, door toevoeging van const ergens kon je compiler alles weg laten optimaliseren )

http://www.gamedev.net/community/forums/topic.asp?topic_id=230443&whichpage=1&#1500805

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op donderdag 22 april 2010 @ 13:17:
Om de componenten aan te spreken met hun variabelenaam en een indexnotatie, vond ik dit wel een mooie oplossing ( lees ook het einde van het topic, door toevoeging van const ergens kon je compiler alles weg laten optimaliseren )

http://www.gamedev.net/community/forums/topic.asp?topic_id=230443&whichpage=1&#1500805
Die is volgens mij wel traag, omdat je compiler twee lookups moet doen en dat niet weg kan optimaliseren.
.oisyn schreef op donderdag 22 april 2010 @ 13:14:
Maar dat geldt dan net zo goed voor arrays, want die requirement is daar ook op van toepassing.
Maar voor arrays staat er (8.3.4.6)

Except where it has been declared for a class (over.sub), the subscript operator [] is interpreted in such a way that E1[E2] is identical to *((E1)+(E2)). Because of the conversion rules that apply to +, if E1 is an array and E2 an integer, then E1[E2] refers to the E2-th member of E1. Therefore, despite its asymmetric appearance, subscripting is a commutative operation.

dus daar worden pointer opgeteld, en dat is volgens mij altijd gewoon een 32bit increment.

[ Voor 36% gewijzigd door Zoijar op 22-04-2010 13:26 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar schreef op donderdag 22 april 2010 @ 13:12:
Overigens weigert VC9 ze anders dan op 32bits te alignen, zelfs met #pragma pack. Alleen met een expliciete declspec gaat het fout.
#pragma pack() (evenals default alignment) zorgt ook niet voor méér ruimte, alleen voor mínder ruimte. Het is derhalve alleen van toepassing op datatypes die groter of gelijk zijn aan de grootte die je opgeeft. #pragma pack(8 ) heeft op een float dus ook geen nut.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

Verwijderd

Zoijar schreef op donderdag 22 april 2010 @ 13:22:
[...]

Die is volgens mij wel traag, omdat je compiler twee lookups moet doen en dat niet weg kan optimaliseren.
Heb je het wel doorgelezen, ze hebben de gegenereerde code bekeken, en het werd toen volledig weggeoptimaliseerd door MSVC 7.1.

http://www.gamedev.net/community/forums/topic.asp?topic_id=230443&whichpage=2&#1507506

[ Voor 21% gewijzigd door Verwijderd op 22-04-2010 13:26 ]


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op donderdag 22 april 2010 @ 13:25:
#pragma pack() (evenals default alignment) zorgt ook niet voor méér ruimte, alleen voor mínder ruimte. Het is derhalve alleen van toepassing op datatypes die groter of gelijk zijn aan de grootte die je opgeeft. #pragma pack(8 ) heeft op een float dus ook geen nut.
Ah ok, dus dat kan je sowieso niet forceren dan op die manier. Logisch wel.
Verwijderd schreef op donderdag 22 april 2010 @ 13:26:
Heb je het wel doorgelezen, ze hebben de gegenereerde code bekeken, en het werd toen volledig weggeoptimaliseerd door MSVC 7.1.

http://www.gamedev.net/community/forums/topic.asp?topic_id=230443&whichpage=2&#1507506
Busted :) Het leek me dat hij nooit kon zien of er niet ergens anders dat stukje geheugen wordt veranderd.

Oh, maar hij past wel de code aan door ze const te maken later. Dan kan het wel. Dat is dan een veiligere manier idd.

[ Voor 5% gewijzigd door Zoijar op 22-04-2010 13:35 ]


Acties:
  • 0 Henk 'm!

Verwijderd

.oisyn schreef op donderdag 22 april 2010 @ 13:25:
[...]


#pragma pack() (evenals default alignment) zorgt ook niet voor méér ruimte, alleen voor mínder ruimte. Het is derhalve alleen van toepassing op datatypes die groter of gelijk zijn aan de grootte die je opgeeft. #pragma pack(8 ) heeft op een float dus ook geen nut.
pack is niet onderdeel van de C of C++ standaard, als je het gebruikt is het niet meer portable tussen verschillende compilers.

Acties:
  • 0 Henk 'm!

Verwijderd

Zoijar schreef op donderdag 22 april 2010 @ 13:32:
[...]

Ah ok, dus dat kan je sowieso niet forceren dan op die manier. Logisch wel.


[...]

Busted :) Het leek me dat hij nooit kon zien of er niet ergens anders dat stukje geheugen wordt veranderd.

Oh, maar hij past wel de code aan door ze const te maken later. Dan kan het wel. Dat is dan een veiligere manier idd.
Inderdaad, daarom dat ik er expliciet bij zei om het topic eens door te lezen, voor het gebruik van de const :)

Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

Verwijderd schreef op donderdag 22 april 2010 @ 13:36:
Inderdaad, daarom dat ik er expliciet bij zei om het topic eens door te lezen, voor het gebruik van de const :)
Ik keek alleen naar de oorspronkelijke code waar je naar linkte... (geen tijd om elk topic door te lezen ;) )

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Zoijar schreef op donderdag 22 april 2010 @ 13:22:
[...]

Die is volgens mij wel traag, omdat je compiler twee lookups moet doen en dat niet weg kan optimaliseren.


[...]

Maar voor arrays staat er (8.3.4.6)

Except where it has been declared for a class (over.sub), the subscript operator [] is interpreted in such a way that E1[E2] is identical to *((E1)+(E2)). Because of the conversion rules that apply to +, if E1 is an array and E2 an integer, then E1[E2] refers to the E2-th member of E1. Therefore, despite its asymmetric appearance, subscripting is a commutative operation.

dus daar worden pointer opgeteld, en dat is volgens mij altijd gewoon een 32bit increment.
Exact. De implicatie is dat als een float een 8-byte alignment zou hebben, dat sizeof(float) dan ook gewoon 8 is :)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Zoijar
  • Registratie: September 2001
  • Niet online

Zoijar

Because he doesn't row...

.oisyn schreef op donderdag 22 april 2010 @ 13:43:
Exact. De implicatie is dat als een float een 8-byte alignment zou hebben, dat sizeof(float) dan ook gewoon 8 is :)
Ik snap je punt. Ik vroeg me dat ook al een beetje af, omdat anders je arrays niet zouden werken. Maar het is niet gegarandeerd dat hij niet iets anders, raars doet bij struct members (dat zou mogen). In de praktijk denk ik dat jou code gewoon altijd werkt. (ik ben hier altijd erg voorzichtig mee omdat ik vroeger op een ultra sparc moest werken, en die crashed bij unaligned reads)

[ Voor 11% gewijzigd door Zoijar op 22-04-2010 13:49 ]


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 14-09 18:19
Bijzonder boeiende discussie, maar mijn laatste vraag is ondertussen nog onbeantwoord:
Bob in "\[C++] properste manier om vector compone..."

Kort: kan de compiler de access in compile time doen wanneer er indexing of iets gelijkaardigs zoals een member pointer wordt gebruikt? Sowieso wanneer dit direct gebeurd, maar ik wil weten of het ook kan wanneer de index dan een van de parameters van een functie is.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 01:28

.oisyn

Moderator Devschuur®

Demotivational Speaker

Ja wat wil je nou? Meten is weten.

Een functie die een pointer/index krijgt zal dat an sich niet compile-time op kunnen lossen, want die ziet alleen maar de offset. Een functie waarbij de boel door de compiler geinlined wordt zou dat wel kunnen. Maar met MSVC++'s link time code generation weet de compiler (of eigenlijk linker) sowieso al heel veel, dus dan zou het weer wel kunnen.

Indices en pointer to members zijn overigens ook mbv templates als compile-time constants te gebruiken.
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
template<class C, class T, T C::* Ptr> struct Accessor
{
    static T & get(C & c) { return c.*Ptr; }
    static T get(C & c) const { return c.*Ptr; }
}

void test()
{
    XVec3 v;
    typedef Accessor<XVec, float, &XVec::x> accessor;

    accessor::get(v) = 34; // dit is vollledig compile-time resolvebaar
}


Maar dit is niet veel anders dan jouw oplossing. Hij is alleen wat generieker (werkt met elke member op elke class, itt members met enkel een bepaalde naam).

[ Voor 100% gewijzigd door .oisyn op 22-04-2010 15:29 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Bob
  • Registratie: Mei 2005
  • Laatst online: 14-09 18:19
Ik hoopte dat iemand onmiddellijk wist of de compiler daar iets mee kan doen. Ik zal het eens testen, heb nog nooit gehoord van compilers die functies gedeeltelijk 'inlinen' omdat 1 van de n parameters at compile time gekend is, maar wie weet.

edit: wat je daar post is qua oplossing hetzelfde als wat ik had, het is een compile time mechanisme om een component te accessen. Als ik dat nu in een functie wil gebruiken heeft die functie nog steeds templates nodig.

C++:
1
2
3
4
template<class Accessor>
void doWithAccess(float input, XVec3 vec){
// iets met Accessor
}


edit2: inderdaad :)

[ Voor 42% gewijzigd door Bob op 22-04-2010 15:32 ]


Acties:
  • 0 Henk 'm!

  • NC83
  • Registratie: Juni 2007
  • Laatst online: 21-08 21:44
Waarom splits je je Process funties niet gewoon in een deel dat het specifiek voor x,y en z doet en een andere deel in een nieuwe functie dat ze delen. Dit lost ook je probleem qua code duplicatie op.

ex-FE Programmer: CMR:DiRT2,DiRT 3, DiRT Showdown, GRID 2, Mad Max


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

volgens mij werkt dit altijd, onafhankelijk van je compiler
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
template<unsigned C> class vec
{
  float v[C];
public:
  float &operator [](unsigned index) { return v[index]; }
  const float &operator [](unsigned index) const { return v[index]; }
  //insert moar methods
};

namespace vector_names { enum value { x, y, z, w }; }

template<vector_names::value T, unsigned C>
float &get(vec<C> &v) { typedef int check_index[T < C ? 1 : -1]; return v[T]; }
template<vector_names::value T, unsigned C>
const float &get<const vec<C> &v) { typedef int check_index[T < C ? 1 : -1]; return v[T]; }

void use()
{
  using namespace vector_names; //sidenote: nu zijn x, y, z, w geen valide variabele namen meer
  vec<3> v3;
  float vx =  get<x>(v3);
  float vz = get<z>(v3);
  float vw = get<w>(v3); //compile error, omdat w niet in een vec<3> zit
}


als je VS2010 gebruikt (zoals blijkt uit de TS zijn gebruik van auto en decltype) ka je de typedef veranderen in een static_assert voor iets beter leesbare code.

voor toegevoegde waarde aan het topic, ook leuk om een swizzle functie meer te bouwen:
C++:
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
template<vector_names::value E1, vector_names::value E2, unsigned C>
vec<2> swizzle(const vec<C> &v)
{ 
  vec<2> result;
  result[0] = get<E1>(v);
  result[1] = get<E2>(v);
  return result;
}
template<vector_names::value E1, vector_names::value E2, vector_names::value E3, unsigned C>
vec<3> swizzle(const vec<C> &v)
{
  vec<3> result;
  result[0] = get<E1>(v);
  result[1] = get<E2>(v); 
  result[2] = get<E3>(v);
  return result;
}

void foo()
{
  using namespace vector_names;
  vec<2> v2; v2[0] = 42.0f; v2[1] = 1337.0f;
  vec<3> bar =  swizzle<x,x,x>(v2); //42,42,42
  v2 = swizzle<y,y>(v2); //1337,1337
  vec<3> fail = swizzle<x, y, z>(v2); //compiled niet, v2 heeft geen z
}


alles niet getest en niet gecompiled, geen garanties :P

[ Voor 30% gewijzigd door MLM op 22-04-2010 21:01 . Reden: syntax highlight ]

-niks-

Pagina: 1