bug_ms_vec_static.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. enum precision
  2. {
  3. packed_highp,
  4. packed_mediump,
  5. packed_lowp,
  6. aligned_highp,
  7. aligned_mediump,
  8. aligned_lowp,
  9. aligned = aligned_highp,
  10. highp = packed_highp,
  11. mediump = packed_mediump,
  12. lowp = packed_lowp,
  13. packed = packed_highp,
  14. defaultp = highp
  15. };
  16. template<precision P>
  17. struct is_aligned
  18. {
  19. static const bool value = false;
  20. };
  21. template<>
  22. struct is_aligned<aligned_lowp>
  23. {
  24. static const bool value = true;
  25. };
  26. template<>
  27. struct is_aligned<aligned_mediump>
  28. {
  29. static const bool value = true;
  30. };
  31. template<>
  32. struct is_aligned<aligned_highp>
  33. {
  34. static const bool value = true;
  35. };
  36. template<typename T, precision P = defaultp> struct vec2;
  37. template<typename T>
  38. struct _swizzle_base0
  39. {
  40. protected:
  41. T& elem(size_t i){ return (reinterpret_cast<T*>(_buffer))[i]; }
  42. T const& elem(size_t i) const{ return (reinterpret_cast<const T*>(_buffer))[i]; }
  43. char _buffer[1];
  44. };
  45. template<typename T, precision P, int E0, int E1, int E2, int E3, bool Aligned>
  46. struct _swizzle_base1 : public _swizzle_base0<T>
  47. {
  48. };
  49. template<typename T, precision P, int E0, int E1, bool Aligned>
  50. struct _swizzle_base1<T, P, E0,E1,-1,-2, Aligned> : public _swizzle_base0<T>
  51. {
  52. vec2<T, P> operator ()() const { return vec2<T, P>(this->elem(E0), this->elem(E1)); }
  53. };
  54. template<typename T, precision P, int E0, int E1, int E2, int E3, int DUPLICATE_ELEMENTS>
  55. struct _swizzle_base2 : public _swizzle_base1<T, P, E0,E1,E2,E3, is_aligned<P>::value>
  56. {
  57. _swizzle_base2& operator= (const T& t)
  58. {
  59. for (int i = 0; i < 2; ++i)
  60. (*this)[i] = t;
  61. return *this;
  62. }
  63. _swizzle_base2& operator= (vec2<T, P> const& that)
  64. {
  65. struct op {
  66. void operator() (T& e, T& t) { e = t; }
  67. };
  68. _apply_op(that, op());
  69. return *this;
  70. }
  71. T& operator[](size_t i)
  72. {
  73. const int offset_dst[4] = { E0, E1, E2, E3 };
  74. return this->elem(offset_dst[i]);
  75. }
  76. T operator[](size_t i) const
  77. {
  78. const int offset_dst[4] = { E0, E1, E2, E3 };
  79. return this->elem(offset_dst[i]);
  80. }
  81. protected:
  82. template<typename U>
  83. void _apply_op(vec2<T, P> const& that, U op)
  84. {
  85. T t[N];
  86. for (int i = 0; i < N; ++i)
  87. t[i] = that[i];
  88. for (int i = 0; i < N; ++i)
  89. op( (*this)[i], t[i] );
  90. }
  91. };
  92. template<typename T, precision P, int E0, int E1, int E2, int E3>
  93. struct _swizzle_base2<T, P, E0,E1,E2,E3, 1> : public _swizzle_base1<T, P, E0,E1,E2,E3, is_aligned<P>::value>
  94. {
  95. struct Stub {};
  96. _swizzle_base2& operator= (Stub const &) { return *this; }
  97. T operator[] (size_t i) const
  98. {
  99. const int offset_dst[4] = { E0, E1, E2, E3 };
  100. return this->elem(offset_dst[i]);
  101. }
  102. };
  103. template<typename T, precision P, int E0, int E1, int E2, int E3>
  104. struct _swizzle : public _swizzle_base2<T, P, E0, E1, E2, E3, (E0 == E1 || E0 == E2 || E0 == E3 || E1 == E2 || E1 == E3 || E2 == E3)>
  105. {
  106. typedef _swizzle_base2<T, P, E0, E1, E2, E3, (E0 == E1 || E0 == E2 || E0 == E3 || E1 == E2 || E1 == E3 || E2 == E3)> base_type;
  107. using base_type::operator=;
  108. operator vec2<T, P> () const { return (*this)(); }
  109. };
  110. template<typename T, precision P>
  111. struct vec2
  112. {
  113. constexpr vec2(T x, T y) :
  114. x(x), y(y)
  115. {}
  116. union
  117. {
  118. struct{ T x, y; };
  119. struct{ T r, g; };
  120. struct{ T s, t; };
  121. struct { _swizzle<T, P, 0,0,-1,-2> xx; };
  122. struct { _swizzle<T, P, 0,0,-1,-2> xy; };
  123. struct { _swizzle<T, P, 0,0,-1,-2> yy; };
  124. struct { _swizzle<T, P, 0,0,-1,-2> yx; };
  125. struct { _swizzle<T, P, 0,0,-1,-2> rr; };
  126. struct { _swizzle<T, P, 0,0,-1,-2> rg; };
  127. struct { _swizzle<T, P, 0,0,-1,-2> gr; };
  128. struct { _swizzle<T, P, 0,0,-1,-2> gg; };
  129. struct { _swizzle<T, P, 0,0,-1,-2> ss; };
  130. struct { _swizzle<T, P, 0,0,-1,-2> st; };
  131. struct { _swizzle<T, P, 0,0,-1,-2> ts; };
  132. struct { _swizzle<T, P, 0,0,-1,-2> tt; };
  133. };
  134. };
  135. typedef vec2<float, defaultp> float2;
  136. // Visual C++ has a bug generating the error: fatal error C1001: An internal error has occurred in the compiler.
  137. float2 const Bar(1.f, 1.f);
  138. int main()
  139. {
  140. return 0;
  141. }