// =====================================================================================================================
//  fennec, a free and open source game engine
//  Copyright © 2025 - 2026  Medusa Slockbower
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================


#ifndef FENNEC_MATH_VECTOR_STORAGE_H
#define FENNEC_MATH_VECTOR_STORAGE_H

#if FENNEC_COMPILER_GCC
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wpedantic"
#endif

#if FENNEC_COMPILER_CLANG
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu-anonymous-struct"
#pragma clang diagnostic ignored "-Wnested-anon-types"
#endif

#if FENNEC_COMPILER_MSVC
#pragma warning(push)
#pragma warning(disable:4201)
#endif

namespace fennec::detail
{

	///
	/// \brief backing storage type for vectors
	/// \tparam SizeV size of the vector
	/// \tparam SwizzleGenT generator for swizzles
	/// \tparam DataT backing data type
	template<size_t SizeV, template<size_t...> class SwizzleGenT, typename DataT> struct vector_storage;

	///
	/// \tparam SwizzleGenT generator for swizzles
	/// \tparam DataT backing data type
	template <template <size_t...> class SwizzleGenT, typename DataT>
	struct vector_storage<1, SwizzleGenT, DataT>
	{
		template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type; //!< swizzle gen type

		vector_storage() = default;

		union {
			DataT data;

			struct { swizzle<0> x; };
			struct { swizzle<0> s; };
			struct { swizzle<0> t; };

			swizzle<0, 0> xx, rr, ss;

			swizzle<0, 0, 0> xxx, rrr, sss;

			swizzle<0, 0, 0, 0> xxxx, rrrr, ssss;
		};
	};


	///
	/// \tparam SwizzleGenT generator for swizzles
	/// \tparam DataT backing data type
	template <template <size_t...> class SwizzleGenT, typename DataT>
	struct vector_storage<2, SwizzleGenT, DataT>
	{
		//
		// alias to allow for increased legibility
		template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type; //!< swizzle gen type

		vector_storage() = default;

		union {
			DataT data;

			struct { swizzle<0> x; swizzle<1> y; };
			struct { swizzle<0> s; swizzle<1> t; };
			struct { swizzle<0> r; swizzle<1> g; };

			swizzle<0,0> xx, rr, ss;
			swizzle<0,1> xy, rg, st;
			swizzle<1,0> yx, gr, ts;
			swizzle<1,1> yy, gg, tt;
			swizzle<0,0,0> xxx, rrr, sss;
			swizzle<0,0,1> xxy, rrg, sst;
			swizzle<0,1,0> xyx, rgr, sts;
			swizzle<0,1,1> xyy, rgg, stt;
			swizzle<1,0,0> yxx, grr, tss;
			swizzle<1,0,1> yxy, grg, tst;
			swizzle<1,1,0> yyx, ggr, tts;
			swizzle<1,1,1> yyy, ggg, ttt;
			swizzle<0,0,0,0> xxxx, rrrr, ssss;
			swizzle<0,0,0,1> xxxy, rrrg, ssst;
			swizzle<0,0,1,0> xxyx, rrgr, ssts;
			swizzle<0,0,1,1> xxyy, rrgg, sstt;
			swizzle<0,1,0,0> xyxx, rgrr, stss;
			swizzle<0,1,0,1> xyxy, rgrg, stst;
			swizzle<0,1,1,0> xyyx, rggr, stts;
			swizzle<0,1,1,1> xyyy, rggg, sttt;
			swizzle<1,0,0,0> yxxx, grrr, tsss;
			swizzle<1,0,0,1> yxxy, grrg, tsst;
			swizzle<1,0,1,0> yxyx, grgr, tsts;
			swizzle<1,0,1,1> yxyy, grgg, tstt;
			swizzle<1,1,0,0> yyxx, ggrr, ttss;
			swizzle<1,1,0,1> yyxy, ggrg, ttst;
			swizzle<1,1,1,0> yyyx, gggr, ttts;
			swizzle<1,1,1,1> yyyy, gggg, tttt;
		};
	};


	///
	/// \tparam SwizzleGenT generator for swizzles
	/// \tparam DataT backing data type
	template <template <size_t...> class SwizzleGenT, typename DataT>
	struct vector_storage<3, SwizzleGenT, DataT>
	{
		template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type; //!< swizzle gen type

		vector_storage() = default;

		union {
			DataT data;

			struct { swizzle<0> x; swizzle<1> y; swizzle<2> z; };
			struct { swizzle<0> s; swizzle<1> t; swizzle<2> p; };
			struct { swizzle<0> r; swizzle<1> g; swizzle<2> b; };

			swizzle<0,0> xx, rr, ss;
			swizzle<0,1> xy, rg, st;
			swizzle<0,2> xz, rb, sp;
			swizzle<1,0> yx, gr, ts;
			swizzle<1,1> yy, gg, tt;
			swizzle<1,2> yz, gb, tp;
			swizzle<2,0> zx, br, ps;
			swizzle<2,1> zy, bg, pt;
			swizzle<2,2> zz, bb, pp;
			swizzle<0,0,0> xxx, rrr, sss;
			swizzle<0,0,1> xxy, rrg, sst;
			swizzle<0,0,2> xxz, rrb, ssp;
			swizzle<0,1,0> xyx, rgr, sts;
			swizzle<0,1,1> xyy, rgg, stt;
			swizzle<0,1,2> xyz, rgb, stp;
			swizzle<0,2,0> xzx, rbr, sps;
			swizzle<0,2,1> xzy, rbg, spt;
			swizzle<0,2,2> xzz, rbb, spp;
			swizzle<1,0,0> yxx, grr, tss;
			swizzle<1,0,1> yxy, grg, tst;
			swizzle<1,0,2> yxz, grb, tsp;
			swizzle<1,1,0> yyx, ggr, tts;
			swizzle<1,1,1> yyy, ggg, ttt;
			swizzle<1,1,2> yyz, ggb, ttp;
			swizzle<1,2,0> yzx, gbr, tps;
			swizzle<1,2,1> yzy, gbg, tpt;
			swizzle<1,2,2> yzz, gbb, tpp;
			swizzle<2,0,0> zxx, brr, pss;
			swizzle<2,0,1> zxy, brg, pst;
			swizzle<2,0,2> zxz, brb, psp;
			swizzle<2,1,0> zyx, bgr, pts;
			swizzle<2,1,1> zyy, bgg, ptt;
			swizzle<2,1,2> zyz, bgb, ptp;
			swizzle<2,2,0> zzx, bbr, pps;
			swizzle<2,2,1> zzy, bbg, ppt;
			swizzle<2,2,2> zzz, bbb, ppp;
			swizzle<0,0,0,0> xxxx, rrrr, ssss;
			swizzle<0,0,0,1> xxxy, rrrg, ssst;
			swizzle<0,0,0,2> xxxz, rrrb, sssp;
			swizzle<0,0,1,0> xxyx, rrgr, ssts;
			swizzle<0,0,1,1> xxyy, rrgg, sstt;
			swizzle<0,0,1,2> xxyz, rrgb, sstp;
			swizzle<0,0,2,0> xxzx, rrbr, ssps;
			swizzle<0,0,2,1> xxzy, rrbg, sspt;
			swizzle<0,0,2,2> xxzz, rrbb, sspp;
			swizzle<0,1,0,0> xyxx, rgrr, stss;
			swizzle<0,1,0,1> xyxy, rgrg, stst;
			swizzle<0,1,0,2> xyxz, rgrb, stsp;
			swizzle<0,1,1,0> xyyx, rggr, stts;
			swizzle<0,1,1,1> xyyy, rggg, sttt;
			swizzle<0,1,1,2> xyyz, rggb, sttp;
			swizzle<0,1,2,0> xyzx, rgbr, stps;
			swizzle<0,1,2,1> xyzy, rgbg, stpt;
			swizzle<0,1,2,2> xyzz, rgbb, stpp;
			swizzle<0,2,0,0> xzxx, rbrr, spss;
			swizzle<0,2,0,1> xzxy, rbrg, spst;
			swizzle<0,2,0,2> xzxz, rbrb, spsp;
			swizzle<0,2,1,0> xzyx, rbgr, spts;
			swizzle<0,2,1,1> xzyy, rbgg, sptt;
			swizzle<0,2,1,2> xzyz, rbgb, sptp;
			swizzle<0,2,2,0> xzzx, rbbr, spps;
			swizzle<0,2,2,1> xzzy, rbbg, sppt;
			swizzle<0,2,2,2> xzzz, rbbb, sppp;
			swizzle<1,0,0,0> yxxx, grrr, tsss;
			swizzle<1,0,0,1> yxxy, grrg, tsst;
			swizzle<1,0,0,2> yxxz, grrb, tssp;
			swizzle<1,0,1,0> yxyx, grgr, tsts;
			swizzle<1,0,1,1> yxyy, grgg, tstt;
			swizzle<1,0,1,2> yxyz, grgb, tstp;
			swizzle<1,0,2,0> yxzx, grbr, tsps;
			swizzle<1,0,2,1> yxzy, grbg, tspt;
			swizzle<1,0,2,2> yxzz, grbb, tspp;
			swizzle<1,1,0,0> yyxx, ggrr, ttss;
			swizzle<1,1,0,1> yyxy, ggrg, ttst;
			swizzle<1,1,0,2> yyxz, ggrb, ttsp;
			swizzle<1,1,1,0> yyyx, gggr, ttts;
			swizzle<1,1,1,1> yyyy, gggg, tttt;
			swizzle<1,1,1,2> yyyz, gggb, tttp;
			swizzle<1,1,2,0> yyzx, ggbr, ttps;
			swizzle<1,1,2,1> yyzy, ggbg, ttpt;
			swizzle<1,1,2,2> yyzz, ggbb, ttpp;
			swizzle<1,2,0,0> yzxx, gbrr, tpss;
			swizzle<1,2,0,1> yzxy, gbrg, tpst;
			swizzle<1,2,0,2> yzxz, gbrb, tpsp;
			swizzle<1,2,1,0> yzyx, gbgr, tpts;
			swizzle<1,2,1,1> yzyy, gbgg, tptt;
			swizzle<1,2,1,2> yzyz, gbgb, tptp;
			swizzle<1,2,2,0> yzzx, gbbr, tpps;
			swizzle<1,2,2,1> yzzy, gbbg, tppt;
			swizzle<1,2,2,2> yzzz, gbbb, tppp;
			swizzle<2,0,0,0> zxxx, brrr, psss;
			swizzle<2,0,0,1> zxxy, brrg, psst;
			swizzle<2,0,0,2> zxxz, brrb, pssp;
			swizzle<2,0,1,0> zxyx, brgr, psts;
			swizzle<2,0,1,1> zxyy, brgg, pstt;
			swizzle<2,0,1,2> zxyz, brgb, pstp;
			swizzle<2,0,2,0> zxzx, brbr, psps;
			swizzle<2,0,2,1> zxzy, brbg, pspt;
			swizzle<2,0,2,2> zxzz, brbb, pspp;
			swizzle<2,1,0,0> zyxx, bgrr, ptss;
			swizzle<2,1,0,1> zyxy, bgrg, ptst;
			swizzle<2,1,0,2> zyxz, bgrb, ptsp;
			swizzle<2,1,1,0> zyyx, bggr, ptts;
			swizzle<2,1,1,1> zyyy, bggg, pttt;
			swizzle<2,1,1,2> zyyz, bggb, pttp;
			swizzle<2,1,2,0> zyzx, bgbr, ptps;
			swizzle<2,1,2,1> zyzy, bgbg, ptpt;
			swizzle<2,1,2,2> zyzz, bgbb, ptpp;
			swizzle<2,2,0,0> zzxx, bbrr, ppss;
			swizzle<2,2,0,1> zzxy, bbrg, ppst;
			swizzle<2,2,0,2> zzxz, bbrb, ppsp;
			swizzle<2,2,1,0> zzyx, bbgr, ppts;
			swizzle<2,2,1,1> zzyy, bbgg, pptt;
			swizzle<2,2,1,2> zzyz, bbgb, pptp;
			swizzle<2,2,2,0> zzzx, bbbr, ppps;
			swizzle<2,2,2,1> zzzy, bbbg, pppt;
			swizzle<2,2,2,2> zzzz, bbbb, pppp;
		};
	};


	///
	/// \tparam SwizzleGenT generator for swizzles
	/// \tparam DataT backing data type
	template <template <size_t...> class SwizzleGenT, typename DataT>
	struct vector_storage<4, SwizzleGenT, DataT>
	{
		template<size_t...IndicesV> using swizzle = typename SwizzleGenT<IndicesV...>::type; //!< swizzle gen type

		vector_storage() = default;

		union {
			DataT data;

			struct { swizzle<0> x; swizzle<1> y; swizzle<2> z; swizzle<3> w; };
			struct { swizzle<0> s; swizzle<1> t; swizzle<2> p; swizzle<3> q; };
			struct { swizzle<0> r; swizzle<1> g; swizzle<2> b; swizzle<3> a; };

			swizzle<0,0> xx, rr, ss;
			swizzle<0,1> xy, rg, st;
			swizzle<0,2> xz, rb, sp;
			swizzle<0,3> xw, ra, sq;
			swizzle<1,0> yx, gr, ts;
			swizzle<1,1> yy, gg, tt;
			swizzle<1,2> yz, gb, tp;
			swizzle<1,3> yw, ga, tq;
			swizzle<2,0> zx, br, ps;
			swizzle<2,1> zy, bg, pt;
			swizzle<2,2> zz, bb, pp;
			swizzle<2,3> zw, ba, pq;
			swizzle<3,0> wx, ar, qs;
			swizzle<3,1> wy, ag, qt;
			swizzle<3,2> wz, ab, qp;
			swizzle<3,3> ww, aa, qq;
			swizzle<0,0,0> xxx, rrr, sss;
			swizzle<0,0,1> xxy, rrg, sst;
			swizzle<0,0,2> xxz, rrb, ssp;
			swizzle<0,0,3> xxw, rra, ssq;
			swizzle<0,1,0> xyx, rgr, sts;
			swizzle<0,1,1> xyy, rgg, stt;
			swizzle<0,1,2> xyz, rgb, stp;
			swizzle<0,1,3> xyw, rga, stq;
			swizzle<0,2,0> xzx, rbr, sps;
			swizzle<0,2,1> xzy, rbg, spt;
			swizzle<0,2,2> xzz, rbb, spp;
			swizzle<0,2,3> xzw, rba, spq;
			swizzle<0,3,0> xwx, rar, sqs;
			swizzle<0,3,1> xwy, rag, sqt;
			swizzle<0,3,2> xwz, rab, sqp;
			swizzle<0,3,3> xww, raa, sqq;
			swizzle<1,0,0> yxx, grr, tss;
			swizzle<1,0,1> yxy, grg, tst;
			swizzle<1,0,2> yxz, grb, tsp;
			swizzle<1,0,3> yxw, gra, tsq;
			swizzle<1,1,0> yyx, ggr, tts;
			swizzle<1,1,1> yyy, ggg, ttt;
			swizzle<1,1,2> yyz, ggb, ttp;
			swizzle<1,1,3> yyw, gga, ttq;
			swizzle<1,2,0> yzx, gbr, tps;
			swizzle<1,2,1> yzy, gbg, tpt;
			swizzle<1,2,2> yzz, gbb, tpp;
			swizzle<1,2,3> yzw, gba, tpq;
			swizzle<1,3,0> ywx, gar, tqs;
			swizzle<1,3,1> ywy, gag, tqt;
			swizzle<1,3,2> ywz, gab, tqp;
			swizzle<1,3,3> yww, gaa, tqq;
			swizzle<2,0,0> zxx, brr, pss;
			swizzle<2,0,1> zxy, brg, pst;
			swizzle<2,0,2> zxz, brb, psp;
			swizzle<2,0,3> zxw, bra, psq;
			swizzle<2,1,0> zyx, bgr, pts;
			swizzle<2,1,1> zyy, bgg, ptt;
			swizzle<2,1,2> zyz, bgb, ptp;
			swizzle<2,1,3> zyw, bga, ptq;
			swizzle<2,2,0> zzx, bbr, pps;
			swizzle<2,2,1> zzy, bbg, ppt;
			swizzle<2,2,2> zzz, bbb, ppp;
			swizzle<2,2,3> zzw, bba, ppq;
			swizzle<2,3,0> zwx, bar, pqs;
			swizzle<2,3,1> zwy, bag, pqt;
			swizzle<2,3,2> zwz, bab, pqp;
			swizzle<2,3,3> zww, baa, pqq;
			swizzle<3,0,0> wxx, arr, qss;
			swizzle<3,0,1> wxy, arg, qst;
			swizzle<3,0,2> wxz, arb, qsp;
			swizzle<3,0,3> wxw, ara, qsq;
			swizzle<3,1,0> wyx, agr, qts;
			swizzle<3,1,1> wyy, agg, qtt;
			swizzle<3,1,2> wyz, agb, qtp;
			swizzle<3,1,3> wyw, aga, qtq;
			swizzle<3,2,0> wzx, abr, qps;
			swizzle<3,2,1> wzy, abg, qpt;
			swizzle<3,2,2> wzz, abb, qpp;
			swizzle<3,2,3> wzw, aba, qpq;
			swizzle<3,3,0> wwx, aar, qqs;
			swizzle<3,3,1> wwy, aag, qqt;
			swizzle<3,3,2> wwz, aab, qqp;
			swizzle<3,3,3> www, aaa, qqq;
			swizzle<0,0,0,0> xxxx, rrrr, ssss;
			swizzle<0,0,0,1> xxxy, rrrg, ssst;
			swizzle<0,0,0,2> xxxz, rrrb, sssp;
			swizzle<0,0,0,3> xxxw, rrra, sssq;
			swizzle<0,0,1,0> xxyx, rrgr, ssts;
			swizzle<0,0,1,1> xxyy, rrgg, sstt;
			swizzle<0,0,1,2> xxyz, rrgb, sstp;
			swizzle<0,0,1,3> xxyw, rrga, sstq;
			swizzle<0,0,2,0> xxzx, rrbr, ssps;
			swizzle<0,0,2,1> xxzy, rrbg, sspt;
			swizzle<0,0,2,2> xxzz, rrbb, sspp;
			swizzle<0,0,2,3> xxzw, rrba, sspq;
			swizzle<0,0,3,0> xxwx, rrar, ssqs;
			swizzle<0,0,3,1> xxwy, rrag, ssqt;
			swizzle<0,0,3,2> xxwz, rrab, ssqp;
			swizzle<0,0,3,3> xxww, rraa, ssqq;
			swizzle<0,1,0,0> xyxx, rgrr, stss;
			swizzle<0,1,0,1> xyxy, rgrg, stst;
			swizzle<0,1,0,2> xyxz, rgrb, stsp;
			swizzle<0,1,0,3> xyxw, rgra, stsq;
			swizzle<0,1,1,0> xyyx, rggr, stts;
			swizzle<0,1,1,1> xyyy, rggg, sttt;
			swizzle<0,1,1,2> xyyz, rggb, sttp;
			swizzle<0,1,1,3> xyyw, rgga, sttq;
			swizzle<0,1,2,0> xyzx, rgbr, stps;
			swizzle<0,1,2,1> xyzy, rgbg, stpt;
			swizzle<0,1,2,2> xyzz, rgbb, stpp;
			swizzle<0,1,2,3> xyzw, rgba, stpq;
			swizzle<0,1,3,0> xywx, rgar, stqs;
			swizzle<0,1,3,1> xywy, rgag, stqt;
			swizzle<0,1,3,2> xywz, rgab, stqp;
			swizzle<0,1,3,3> xyww, rgaa, stqq;
			swizzle<0,2,0,0> xzxx, rbrr, spss;
			swizzle<0,2,0,1> xzxy, rbrg, spst;
			swizzle<0,2,0,2> xzxz, rbrb, spsp;
			swizzle<0,2,0,3> xzxw, rbra, spsq;
			swizzle<0,2,1,0> xzyx, rbgr, spts;
			swizzle<0,2,1,1> xzyy, rbgg, sptt;
			swizzle<0,2,1,2> xzyz, rbgb, sptp;
			swizzle<0,2,1,3> xzyw, rbga, sptq;
			swizzle<0,2,2,0> xzzx, rbbr, spps;
			swizzle<0,2,2,1> xzzy, rbbg, sppt;
			swizzle<0,2,2,2> xzzz, rbbb, sppp;
			swizzle<0,2,2,3> xzzw, rbba, sppq;
			swizzle<0,2,3,0> xzwx, rbar, spqs;
			swizzle<0,2,3,1> xzwy, rbag, spqt;
			swizzle<0,2,3,2> xzwz, rbab, spqp;
			swizzle<0,2,3,3> xzww, rbaa, spqq;
			swizzle<0,3,0,0> xwxx, rarr, sqss;
			swizzle<0,3,0,1> xwxy, rarg, sqst;
			swizzle<0,3,0,2> xwxz, rarb, sqsp;
			swizzle<0,3,0,3> xwxw, rara, sqsq;
			swizzle<0,3,1,0> xwyx, ragr, sqts;
			swizzle<0,3,1,1> xwyy, ragg, sqtt;
			swizzle<0,3,1,2> xwyz, ragb, sqtp;
			swizzle<0,3,1,3> xwyw, raga, sqtq;
			swizzle<0,3,2,0> xwzx, rabr, sqps;
			swizzle<0,3,2,1> xwzy, rabg, sqpt;
			swizzle<0,3,2,2> xwzz, rabb, sqpp;
			swizzle<0,3,2,3> xwzw, raba, sqpq;
			swizzle<0,3,3,0> xwwx, raar, sqqs;
			swizzle<0,3,3,1> xwwy, raag, sqqt;
			swizzle<0,3,3,2> xwwz, raab, sqqp;
			swizzle<0,3,3,3> xwww, raaa, sqqq;
			swizzle<1,0,0,0> yxxx, grrr, tsss;
			swizzle<1,0,0,1> yxxy, grrg, tsst;
			swizzle<1,0,0,2> yxxz, grrb, tssp;
			swizzle<1,0,0,3> yxxw, grra, tssq;
			swizzle<1,0,1,0> yxyx, grgr, tsts;
			swizzle<1,0,1,1> yxyy, grgg, tstt;
			swizzle<1,0,1,2> yxyz, grgb, tstp;
			swizzle<1,0,1,3> yxyw, grga, tstq;
			swizzle<1,0,2,0> yxzx, grbr, tsps;
			swizzle<1,0,2,1> yxzy, grbg, tspt;
			swizzle<1,0,2,2> yxzz, grbb, tspp;
			swizzle<1,0,2,3> yxzw, grba, tspq;
			swizzle<1,0,3,0> yxwx, grar, tsqs;
			swizzle<1,0,3,1> yxwy, grag, tsqt;
			swizzle<1,0,3,2> yxwz, grab, tsqp;
			swizzle<1,0,3,3> yxww, graa, tsqq;
			swizzle<1,1,0,0> yyxx, ggrr, ttss;
			swizzle<1,1,0,1> yyxy, ggrg, ttst;
			swizzle<1,1,0,2> yyxz, ggrb, ttsp;
			swizzle<1,1,0,3> yyxw, ggra, ttsq;
			swizzle<1,1,1,0> yyyx, gggr, ttts;
			swizzle<1,1,1,1> yyyy, gggg, tttt;
			swizzle<1,1,1,2> yyyz, gggb, tttp;
			swizzle<1,1,1,3> yyyw, ggga, tttq;
			swizzle<1,1,2,0> yyzx, ggbr, ttps;
			swizzle<1,1,2,1> yyzy, ggbg, ttpt;
			swizzle<1,1,2,2> yyzz, ggbb, ttpp;
			swizzle<1,1,2,3> yyzw, ggba, ttpq;
			swizzle<1,1,3,0> yywx, ggar, ttqs;
			swizzle<1,1,3,1> yywy, ggag, ttqt;
			swizzle<1,1,3,2> yywz, ggab, ttqp;
			swizzle<1,1,3,3> yyww, ggaa, ttqq;
			swizzle<1,2,0,0> yzxx, gbrr, tpss;
			swizzle<1,2,0,1> yzxy, gbrg, tpst;
			swizzle<1,2,0,2> yzxz, gbrb, tpsp;
			swizzle<1,2,0,3> yzxw, gbra, tpsq;
			swizzle<1,2,1,0> yzyx, gbgr, tpts;
			swizzle<1,2,1,1> yzyy, gbgg, tptt;
			swizzle<1,2,1,2> yzyz, gbgb, tptp;
			swizzle<1,2,1,3> yzyw, gbga, tptq;
			swizzle<1,2,2,0> yzzx, gbbr, tpps;
			swizzle<1,2,2,1> yzzy, gbbg, tppt;
			swizzle<1,2,2,2> yzzz, gbbb, tppp;
			swizzle<1,2,2,3> yzzw, gbba, tppq;
			swizzle<1,2,3,0> yzwx, gbar, tpqs;
			swizzle<1,2,3,1> yzwy, gbag, tpqt;
			swizzle<1,2,3,2> yzwz, gbab, tpqp;
			swizzle<1,2,3,3> yzww, gbaa, tpqq;
			swizzle<1,3,0,0> ywxx, garr, tqss;
			swizzle<1,3,0,1> ywxy, garg, tqst;
			swizzle<1,3,0,2> ywxz, garb, tqsp;
			swizzle<1,3,0,3> ywxw, gara, tqsq;
			swizzle<1,3,1,0> ywyx, gagr, tqts;
			swizzle<1,3,1,1> ywyy, gagg, tqtt;
			swizzle<1,3,1,2> ywyz, gagb, tqtp;
			swizzle<1,3,1,3> ywyw, gaga, tqtq;
			swizzle<1,3,2,0> ywzx, gabr, tqps;
			swizzle<1,3,2,1> ywzy, gabg, tqpt;
			swizzle<1,3,2,2> ywzz, gabb, tqpp;
			swizzle<1,3,2,3> ywzw, gaba, tqpq;
			swizzle<1,3,3,0> ywwx, gaar, tqqs;
			swizzle<1,3,3,1> ywwy, gaag, tqqt;
			swizzle<1,3,3,2> ywwz, gaab, tqqp;
			swizzle<1,3,3,3> ywww, gaaa, tqqq;
			swizzle<2,0,0,0> zxxx, brrr, psss;
			swizzle<2,0,0,1> zxxy, brrg, psst;
			swizzle<2,0,0,2> zxxz, brrb, pssp;
			swizzle<2,0,0,3> zxxw, brra, pssq;
			swizzle<2,0,1,0> zxyx, brgr, psts;
			swizzle<2,0,1,1> zxyy, brgg, pstt;
			swizzle<2,0,1,2> zxyz, brgb, pstp;
			swizzle<2,0,1,3> zxyw, brga, pstq;
			swizzle<2,0,2,0> zxzx, brbr, psps;
			swizzle<2,0,2,1> zxzy, brbg, pspt;
			swizzle<2,0,2,2> zxzz, brbb, pspp;
			swizzle<2,0,2,3> zxzw, brba, pspq;
			swizzle<2,0,3,0> zxwx, brar, psqs;
			swizzle<2,0,3,1> zxwy, brag, psqt;
			swizzle<2,0,3,2> zxwz, brab, psqp;
			swizzle<2,0,3,3> zxww, braa, psqq;
			swizzle<2,1,0,0> zyxx, bgrr, ptss;
			swizzle<2,1,0,1> zyxy, bgrg, ptst;
			swizzle<2,1,0,2> zyxz, bgrb, ptsp;
			swizzle<2,1,0,3> zyxw, bgra, ptsq;
			swizzle<2,1,1,0> zyyx, bggr, ptts;
			swizzle<2,1,1,1> zyyy, bggg, pttt;
			swizzle<2,1,1,2> zyyz, bggb, pttp;
			swizzle<2,1,1,3> zyyw, bgga, pttq;
			swizzle<2,1,2,0> zyzx, bgbr, ptps;
			swizzle<2,1,2,1> zyzy, bgbg, ptpt;
			swizzle<2,1,2,2> zyzz, bgbb, ptpp;
			swizzle<2,1,2,3> zyzw, bgba, ptpq;
			swizzle<2,1,3,0> zywx, bgar, ptqs;
			swizzle<2,1,3,1> zywy, bgag, ptqt;
			swizzle<2,1,3,2> zywz, bgab, ptqp;
			swizzle<2,1,3,3> zyww, bgaa, ptqq;
			swizzle<2,2,0,0> zzxx, bbrr, ppss;
			swizzle<2,2,0,1> zzxy, bbrg, ppst;
			swizzle<2,2,0,2> zzxz, bbrb, ppsp;
			swizzle<2,2,0,3> zzxw, bbra, ppsq;
			swizzle<2,2,1,0> zzyx, bbgr, ppts;
			swizzle<2,2,1,1> zzyy, bbgg, pptt;
			swizzle<2,2,1,2> zzyz, bbgb, pptp;
			swizzle<2,2,1,3> zzyw, bbga, pptq;
			swizzle<2,2,2,0> zzzx, bbbr, ppps;
			swizzle<2,2,2,1> zzzy, bbbg, pppt;
			swizzle<2,2,2,2> zzzz, bbbb, pppp;
			swizzle<2,2,2,3> zzzw, bbba, pppq;
			swizzle<2,2,3,0> zzwx, bbar, ppqs;
			swizzle<2,2,3,1> zzwy, bbag, ppqt;
			swizzle<2,2,3,2> zzwz, bbab, ppqp;
			swizzle<2,2,3,3> zzww, bbaa, ppqq;
			swizzle<2,3,0,0> zwxx, barr, pqss;
			swizzle<2,3,0,1> zwxy, barg, pqst;
			swizzle<2,3,0,2> zwxz, barb, pqsp;
			swizzle<2,3,0,3> zwxw, bara, pqsq;
			swizzle<2,3,1,0> zwyx, bagr, pqts;
			swizzle<2,3,1,1> zwyy, bagg, pqtt;
			swizzle<2,3,1,2> zwyz, bagb, pqtp;
			swizzle<2,3,1,3> zwyw, baga, pqtq;
			swizzle<2,3,2,0> zwzx, babr, pqps;
			swizzle<2,3,2,1> zwzy, babg, pqpt;
			swizzle<2,3,2,2> zwzz, babb, pqpp;
			swizzle<2,3,2,3> zwzw, baba, pqpq;
			swizzle<2,3,3,0> zwwx, baar, pqqs;
			swizzle<2,3,3,1> zwwy, baag, pqqt;
			swizzle<2,3,3,2> zwwz, baab, pqqp;
			swizzle<2,3,3,3> zwww, baaa, pqqq;
			swizzle<3,0,0,0> wxxx, arrr, qsss;
			swizzle<3,0,0,1> wxxy, arrg, qsst;
			swizzle<3,0,0,2> wxxz, arrb, qssp;
			swizzle<3,0,0,3> wxxw, arra, qssq;
			swizzle<3,0,1,0> wxyx, argr, qsts;
			swizzle<3,0,1,1> wxyy, argg, qstt;
			swizzle<3,0,1,2> wxyz, argb, qstp;
			swizzle<3,0,1,3> wxyw, arga, qstq;
			swizzle<3,0,2,0> wxzx, arbr, qsps;
			swizzle<3,0,2,1> wxzy, arbg, qspt;
			swizzle<3,0,2,2> wxzz, arbb, qspp;
			swizzle<3,0,2,3> wxzw, arba, qspq;
			swizzle<3,0,3,0> wxwx, arar, qsqs;
			swizzle<3,0,3,1> wxwy, arag, qsqt;
			swizzle<3,0,3,2> wxwz, arab, qsqp;
			swizzle<3,0,3,3> wxww, araa, qsqq;
			swizzle<3,1,0,0> wyxx, agrr, qtss;
			swizzle<3,1,0,1> wyxy, agrg, qtst;
			swizzle<3,1,0,2> wyxz, agrb, qtsp;
			swizzle<3,1,0,3> wyxw, agra, qtsq;
			swizzle<3,1,1,0> wyyx, aggr, qtts;
			swizzle<3,1,1,1> wyyy, aggg, qttt;
			swizzle<3,1,1,2> wyyz, aggb, qttp;
			swizzle<3,1,1,3> wyyw, agga, qttq;
			swizzle<3,1,2,0> wyzx, agbr, qtps;
			swizzle<3,1,2,1> wyzy, agbg, qtpt;
			swizzle<3,1,2,2> wyzz, agbb, qtpp;
			swizzle<3,1,2,3> wyzw, agba, qtpq;
			swizzle<3,1,3,0> wywx, agar, qtqs;
			swizzle<3,1,3,1> wywy, agag, qtqt;
			swizzle<3,1,3,2> wywz, agab, qtqp;
			swizzle<3,1,3,3> wyww, agaa, qtqq;
			swizzle<3,2,0,0> wzxx, abrr, qpss;
			swizzle<3,2,0,1> wzxy, abrg, qpst;
			swizzle<3,2,0,2> wzxz, abrb, qpsp;
			swizzle<3,2,0,3> wzxw, abra, qpsq;
			swizzle<3,2,1,0> wzyx, abgr, qpts;
			swizzle<3,2,1,1> wzyy, abgg, qptt;
			swizzle<3,2,1,2> wzyz, abgb, qptp;
			swizzle<3,2,1,3> wzyw, abga, qptq;
			swizzle<3,2,2,0> wzzx, abbr, qpps;
			swizzle<3,2,2,1> wzzy, abbg, qppt;
			swizzle<3,2,2,2> wzzz, abbb, qppp;
			swizzle<3,2,2,3> wzzw, abba, qppq;
			swizzle<3,2,3,0> wzwx, abar, qpqs;
			swizzle<3,2,3,1> wzwy, abag, qpqt;
			swizzle<3,2,3,2> wzwz, abab, qpqp;
			swizzle<3,2,3,3> wzww, abaa, qpqq;
			swizzle<3,3,0,0> wwxx, aarr, qqss;
			swizzle<3,3,0,1> wwxy, aarg, qqst;
			swizzle<3,3,0,2> wwxz, aarb, qqsp;
			swizzle<3,3,0,3> wwxw, aara, qqsq;
			swizzle<3,3,1,0> wwyx, aagr, qqts;
			swizzle<3,3,1,1> wwyy, aagg, qqtt;
			swizzle<3,3,1,2> wwyz, aagb, qqtp;
			swizzle<3,3,1,3> wwyw, aaga, qqtq;
			swizzle<3,3,2,0> wwzx, aabr, qqps;
			swizzle<3,3,2,1> wwzy, aabg, qqpt;
			swizzle<3,3,2,2> wwzz, aabb, qqpp;
			swizzle<3,3,2,3> wwzw, aaba, qqpq;
			swizzle<3,3,3,0> wwwx, aaar, qqqs;
			swizzle<3,3,3,1> wwwy, aaag, qqqt;
			swizzle<3,3,3,2> wwwz, aaab, qqqp;
			swizzle<3,3,3,3> wwww, aaaa, qqqq;
		};
	};

}

#ifdef FENNEC_COMPILER_GCC
#pragma GCC diagnostic pop
#endif

#ifdef FENNEC_COMPILER_CLANG
#pragma clang diagnostic pop
#endif

#if FENNEC_COMPILER_MSVC
#pragma warning(pop)
#endif

#endif // FENNEC_MATH_VECTOR_STORAGE_H
