C++0x and direct constant?

G

Groovounet

The following code is working on VC2010 but I don't think it's a
standard behaviours as it doesn't work on GCC as it says that Mask
must be a direct constant.

Is there some changes in C++0x?
Is there a workaround in C++98?

template<int a, int b, int c, int d>
__m128 swizzle(glm::vec4 const & v)
{
enum {Mask = ((d << 6) | (c << 4) | (b << 2) | (a << 0))};
__m128 Src = _mm_set_ps(v.w, v.z, v.y, v.x);
return _mm_shuffle_ps(Src, Src, Mask);
}

int main()
{
__m128 Data = swizzle<0, 1, 2, 3>(glm::vec4(1.0f, 2.0f, 3.0f, 4.0f));

return 0;
}
 
G

Groovounet

A workaround is:
template <int Value>
struct mask
{
enum{value = Value};
};

template<int a, int b, int c, int d>
__m128 swizzle(glm::vec4 const & v)
{
__m128 Src = _mm_set_ps(v.w, v.z, v.y, v.x);
return _mm_shuffle_ps(Src, Src, mask<(d << 6) | (c << 4) | (b << 2) |
(a << 0)>::value);
}

It feels good enough actually
 
J

James Kanze

The following code is working on VC2010 but I don't think it's a
standard behaviours as it doesn't work on GCC as it says that Mask
must be a direct constant.
Is there some changes in C++0x?
Is there a workaround in C++98?
template<int a, int b, int c, int d>
__m128 swizzle(glm::vec4 const & v)
{
enum {Mask = ((d << 6) | (c << 4) | (b << 2) | (a << 0))};
__m128 Src = _mm_set_ps(v.w, v.z, v.y, v.x);
return _mm_shuffle_ps(Src, Src, Mask);
}
int main()
{
__m128 Data = swizzle<0, 1, 2, 3>(glm::vec4(1.0f, 2.0f, 3.0f, 4.0f));
return 0;
}

It would help if you'd post a cut down, compilable example. The
following works for me with g++ 4.4.2, and I don't see why it
shouldn't:

template<int a, int b>
void test()
{
enum { M = (a << 8) | (b << 4) };
}

int
main()
{
test<1, 2>();
}

I suspect that your problem is elsewhere (or you're using an
older version of g++, which had a bug which has since been
fixed).
 
M

Miles Bader

Groovounet said:
template<int a, int b, int c, int d>
__m128 swizzle(glm::vec4 const & v)
{
enum {Mask = ((d << 6) | (c << 4) | (b << 2) | (a << 0))};
__m128 Src = _mm_set_ps(v.w, v.z, v.y, v.x);
return _mm_shuffle_ps(Src, Src, Mask);
}

I'm curious -- why do you use the enum?

I mean, why not just use something like:

template<int a, int b, int c, int d>
__m128 swizzle(glm::vec4 const & v)
{
__m128 Src = _mm_set_ps(v.w, v.z, v.y, v.x);
return _mm_shuffle_ps(Src, Src, ((d << 6) | (c << 4) | (b << 2) | (a << 0)));
}

?

-Miles
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,596
Members
45,128
Latest member
ElwoodPhil
Top