Parcourir la source

Replace pre C++20 hacks and start using requires() where appropriate

Panagiotis Christopoulos Charitos il y a 1 an
Parent
commit
9624b6f744

+ 1 - 2
AnKi/Math/Axisang.h

@@ -183,8 +183,7 @@ public:
 
 	/// @name Other
 	/// @{
-	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	String toString() const
+	String toString() const requires(std::is_floating_point<T>::value)
 	{
 		return String().sprintf("%f %f %f | %f", m_axis.x(), m_axis.y(), m_axis.z(), m_ang);
 	}

+ 1 - 2
AnKi/Math/Euler.h

@@ -145,8 +145,7 @@ public:
 
 	/// @name Other
 	/// @{
-	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	String toString() const
+	String toString() const requires(std::is_floating_point<T>::value)
 	{
 		return String().sprintf("%f %f %f", m_vec.m_x, m_vec.m_y, m_vec.m_z);
 	}

+ 14 - 14
AnKi/Math/Functions.h

@@ -66,14 +66,14 @@ inline T atan2(const T x, const T y)
 void sinCos(const F32 a, F32& sina, F32& cosa);
 void sinCos(const F64 a, F64& sina, F64& cosa);
 
-template<typename T, ANKI_ENABLE(std::is_floating_point<T>::value)>
-inline T sqrt(const T x)
+template<typename T>
+inline T sqrt(const T x) requires(std::is_floating_point<T>::value)
 {
 	return std::sqrt(x);
 }
 
-template<typename T, ANKI_ENABLE(std::is_integral<T>::value)>
-inline T sqrt(const T x)
+template<typename T>
+inline T sqrt(const T x) requires(std::is_integral<T>::value)
 {
 	return T(std::sqrt(F64(x)));
 }
@@ -105,15 +105,15 @@ inline T modf(T x, T& intPart)
 }
 
 /// The same as abs/fabs. For ints.
-template<typename T, ANKI_ENABLE(std::is_integral<T>::value&& std::is_signed<T>::value)>
-inline constexpr T absolute(const T f)
+template<typename T>
+inline constexpr T absolute(const T f) requires(std::is_integral<T>::value&& std::is_signed<T>::value)
 {
 	return (f < T(0)) ? -f : f;
 }
 
 /// The same as abs/fabs. For floats.
-template<typename T, ANKI_ENABLE(std::is_floating_point<T>::value)>
-inline constexpr T absolute(const T f)
+template<typename T>
+inline constexpr T absolute(const T f) requires(std::is_floating_point<T>::value)
 {
 	return fabs(f);
 }
@@ -130,20 +130,20 @@ inline constexpr T log2(const T x)
 	return T(std::log2(x));
 }
 
-template<typename T, ANKI_ENABLE(std::is_floating_point<T>::value)>
-inline constexpr Bool isZero(const T f, const T e = kEpsilonf)
+template<typename T>
+inline constexpr Bool isZero(const T f, const T e = kEpsilonf) requires(std::is_floating_point<T>::value)
 {
 	return absolute<T>(f) < e;
 }
 
-template<typename T, ANKI_ENABLE(std::is_integral<T>::value)>
-inline constexpr Bool isZero(const T f)
+template<typename T>
+inline constexpr Bool isZero(const T f) requires(std::is_integral<T>::value)
 {
 	return f == 0;
 }
 
-template<typename T, ANKI_ENABLE(std::is_floating_point<T>::value)>
-inline constexpr T toRad(const T degrees)
+template<typename T>
+inline constexpr T toRad(const T degrees) requires(std::is_floating_point<T>::value)
 {
 	return degrees * (kPi / T(180));
 }

+ 5 - 5
AnKi/Math/GenVecAccessors.py

@@ -27,13 +27,10 @@ def gen_accessors():
 				for c in range(0, 4 if vec_components > 2 else 1):
 					for d in range(0, 4 if vec_components > 3 else 1):
 						arr = [a, b, c, d]
-
-						# Enable it
 						max_comp = max(max(max(a, b), c), d)
-						h += "\n\tANKI_ENABLE_IF_EXPRESSION(N > " + str(max_comp) + ")\n"
 
 						# Return value
-						h += "\t"
+						h += "\n\t"
 						if vec_components == 1:
 							h += scalar + " "
 						else:
@@ -45,9 +42,12 @@ def gen_accessors():
 						for i in range(0, vec_components):
 							method_name += index_to_component(arr[i])
 						h += method_name
+						h += "() const"
+
+						# requires
+						h += " requires(kTComponentCount > " + str(max_comp) + ")\n"
 
 						# Write the body
-						h += "() const\n"
 						h += "\t{\n"
 						h += "\t\treturn " + gen_vec_class_name(vec_components) + "("
 						for i in range(0, vec_components):

+ 58 - 100
AnKi/Math/Mat.h

@@ -39,9 +39,11 @@ public:
 	static constexpr U kRowCount = kTRowCount; ///< Number of rows
 	static constexpr U kColumnCount = kTColumnCount; ///< Number of columns
 	static constexpr U kSize = kTRowCount * kTColumnCount; ///< Number of total elements
+
+	static constexpr Bool kIsSquare = kTColumnCount == kTRowCount;
 	static constexpr Bool kHasSimd = kTColumnCount == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
-	static constexpr Bool kHasMat4Simd = kTRowCount == 4 && kTColumnCount == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
-	static constexpr Bool kHasMat3x4Simd = kTRowCount == 3 && kTColumnCount == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
+	static constexpr Bool kIs4x4Simd = kTRowCount == 4 && kTColumnCount == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
+	static constexpr Bool kIs3x4Simd = kTRowCount == 3 && kTColumnCount == 4 && std::is_same<T, F32>::value && ANKI_ENABLE_SIMD;
 
 	/// @name Constructors
 	/// @{
@@ -77,8 +79,7 @@ public:
 
 	// 3x3 specific constructors
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 3)
-	constexpr TMat(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22)
+	constexpr TMat(T m00, T m01, T m02, T m10, T m11, T m12, T m20, T m21, T m22) requires(kSize == 9)
 	{
 		auto& m = *this;
 		m(0, 0) = m00;
@@ -92,28 +93,25 @@ public:
 		m(2, 2) = m22;
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 3)
-	explicit constexpr TMat(const TQuat<T>& q)
+	explicit constexpr TMat(const TQuat<T>& q) requires(kSize == 9)
 	{
 		setRotationPart(q);
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 3)
-	explicit constexpr TMat(const TEuler<T>& e)
+	explicit constexpr TMat(const TEuler<T>& e) requires(kSize == 9)
 	{
 		setRotationPart(e);
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 3)
-	explicit constexpr TMat(const TAxisang<T>& axisang)
+	explicit constexpr TMat(const TAxisang<T>& axisang) requires(kSize == 9)
 	{
 		setRotationPart(axisang);
 	}
 
 	// 4x4 specific constructors
 
-	ANKI_ENABLE_METHOD(kTRowCount == 4 && kTColumnCount == 4)
-	constexpr TMat(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31, T m32, T m33)
+	constexpr TMat(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23, T m30, T m31, T m32,
+				   T m33) requires(kSize == 16)
 	{
 		auto& m = *this;
 		m(0, 0) = m00;
@@ -134,8 +132,7 @@ public:
 		m(3, 3) = m33;
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 4 && kTColumnCount == 4)
-	constexpr TMat(const TVec<T, 4>& translation, const TMat<T, 3, 3>& rotation, const T scale = T(1))
+	constexpr TMat(const TVec<T, 4>& translation, const TMat<T, 3, 3>& rotation, const T scale = T(1)) requires(kSize == 16)
 	{
 		if(isZero<T>(scale - T(1)))
 		{
@@ -152,15 +149,13 @@ public:
 		m(3, 0) = m(3, 1) = m(3, 2) = T(0);
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 4 && kTColumnCount == 4)
-	explicit constexpr TMat(const TTransform<T>& t)
+	explicit constexpr TMat(const TTransform<T>& t) requires(kSize == 16)
 		: TMat(t.getOrigin().xyz1(), t.getRotation().getRotationPart(), t.getScale())
 	{
 	}
 
 	/// Set a 4x4 matrix using a 3x4 for the first 3 rows and a vec4 for the 4rth row.
-	ANKI_ENABLE_METHOD(kTRowCount == 4 && kTColumnCount == 4)
-	explicit constexpr TMat(const TMat<T, 3, 4>& m3, const TVec<T, 4>& row3)
+	explicit constexpr TMat(const TMat<T, 3, 4>& m3, const TVec<T, 4>& row3) requires(kSize == 16)
 	{
 		setRow(0, m3.getRow(0));
 		setRow(1, m3.getRow(1));
@@ -170,8 +165,7 @@ public:
 
 	// 3x4 specific constructors
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4)
-	constexpr TMat(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23)
+	constexpr TMat(T m00, T m01, T m02, T m03, T m10, T m11, T m12, T m13, T m20, T m21, T m22, T m23) requires(kSize == 12)
 	{
 		auto& m = *this;
 		m(0, 0) = m00;
@@ -188,8 +182,7 @@ public:
 		m(2, 3) = m23;
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4)
-	explicit constexpr TMat(const TMat<T, 4, 4>& m4)
+	explicit constexpr TMat(const TMat<T, 4, 4>& m4) requires(kSize == 12)
 	{
 		ANKI_ASSERT(m4(3, 0) == T(0) && m4(3, 1) == T(0) && m4(3, 2) == T(0) && m4(3, 3) == T(1));
 		m_rows[0] = m4.getRow(0);
@@ -197,8 +190,7 @@ public:
 		m_rows[2] = m4.getRow(2);
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4)
-	explicit constexpr TMat(const TVec<T, 3>& translation, const TMat<T, 3, 3>& rotation, const T scale = T(1))
+	explicit constexpr TMat(const TVec<T, 3>& translation, const TMat<T, 3, 3>& rotation, const T scale = T(1)) requires(kSize == 12)
 	{
 		if(isZero<T>(scale - T(1)))
 		{
@@ -212,26 +204,22 @@ public:
 		setTranslationPart(translation);
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4)
-	explicit constexpr TMat(const TVec<T, 3>& translation, const TQuat<T>& q, const T scale = T(1))
+	explicit constexpr TMat(const TVec<T, 3>& translation, const TQuat<T>& q, const T scale = T(1)) requires(kSize == 12)
 		: TMat(translation, TMat<T, 3, 3>(q), scale)
 	{
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4)
-	explicit constexpr TMat(const TVec<T, 3>& translation, const TEuler<T>& b, const T scale = T(1))
+	explicit constexpr TMat(const TVec<T, 3>& translation, const TEuler<T>& b, const T scale = T(1)) requires(kSize == 12)
 		: TMat(translation, TMat<T, 3, 3>(b), scale)
 	{
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4)
-	explicit constexpr TMat(const TVec<T, 3>& translation, const TAxisang<T>& b, const T scale = T(1))
+	explicit constexpr TMat(const TVec<T, 3>& translation, const TAxisang<T>& b, const T scale = T(1)) requires(kSize == 12)
 		: TMat(translation, TMat<T, 3, 3>(b), scale)
 	{
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4)
-	explicit constexpr TMat(const TTransform<T>& t)
+	explicit constexpr TMat(const TTransform<T>& t) requires(kSize == 12)
 		: TMat(t.getOrigin().xyz(), t.getRotation().getRotationPart(), t.getScale())
 	{
 	}
@@ -311,8 +299,7 @@ public:
 		return *this;
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == kTColumnCount && !kHasMat4Simd)
-	TMat operator*(const TMat& b) const
+	TMat operator*(const TMat& b) const requires(kIsSquare && !kIs4x4Simd)
 	{
 		TMat out;
 		const TMat& a = *this;
@@ -331,8 +318,7 @@ public:
 	}
 
 #if ANKI_ENABLE_SIMD
-	ANKI_ENABLE_METHOD(kHasMat4Simd)
-	TMat operator*(const TMat& b) const
+	TMat operator*(const TMat& b) const requires(kIs4x4Simd)
 	{
 		TMat out;
 		const auto& m = *this;
@@ -485,8 +471,7 @@ public:
 
 	/// @name Operators with other types
 	/// @{
-	ANKI_ENABLE_METHOD(!kHasSimd)
-	ColumnVec operator*(const RowVec& v) const
+	ColumnVec operator*(const RowVec& v) const requires(!kHasSimd)
 	{
 		const TMat& m = *this;
 		ColumnVec out;
@@ -503,8 +488,7 @@ public:
 	}
 
 #if ANKI_SIMD_SSE
-	ANKI_ENABLE_METHOD(kHasMat4Simd)
-	ColumnVec operator*(const RowVec& v) const
+	ColumnVec operator*(const RowVec& v) const requires(kIs4x4Simd)
 	{
 		__m128 a = _mm_mul_ps(m_simd[0], v.getSimd());
 		__m128 b = _mm_mul_ps(m_simd[1], v.getSimd());
@@ -517,8 +501,7 @@ public:
 		return RowVec(_mm_hadd_ps(a, c));
 	}
 
-	ANKI_ENABLE_METHOD(kHasMat3x4Simd)
-	ColumnVec operator*(const RowVec& v) const
+	ColumnVec operator*(const RowVec& v) const requires(kIs3x4Simd)
 	{
 		__m128 a = _mm_mul_ps(m_simd[0], v.getSimd());
 		__m128 b = _mm_mul_ps(m_simd[1], v.getSimd());
@@ -532,8 +515,7 @@ public:
 
 #else
 
-	ANKI_ENABLE_METHOD(kHasSimd)
-	ColumnVec operator*(const RowVec& v) const
+	ColumnVec operator*(const RowVec& v) const requires(kHasSimd)
 	{
 		ColumnVec out;
 		for(U i = 0; i < kTRowCount; i++)
@@ -559,8 +541,7 @@ public:
 		setRow(2, c);
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount > 3)
-	void setRows(const RowVec& a, const RowVec& b, const RowVec& c, const RowVec& d)
+	void setRows(const RowVec& a, const RowVec& b, const RowVec& c, const RowVec& d) requires(kTRowCount > 3)
 	{
 		setRows(a, b, c);
 		setRow(3, d);
@@ -578,8 +559,7 @@ public:
 		c = getRow(2);
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount > 3)
-	void getRows(RowVec& a, RowVec& b, RowVec& c, RowVec& d) const
+	void getRows(RowVec& a, RowVec& b, RowVec& c, RowVec& d) const requires(kTRowCount > 3)
 	{
 		getRows(a, b, c);
 		d = getRow(3);
@@ -600,8 +580,7 @@ public:
 		setColumn(2, c);
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount > 3)
-	void setColumns(const ColumnVec& a, const ColumnVec& b, const ColumnVec& c, const ColumnVec& d)
+	void setColumns(const ColumnVec& a, const ColumnVec& b, const ColumnVec& c, const ColumnVec& d) requires(kTColumnCount > 3)
 	{
 		setColumns(a, b, c);
 		setColumn(3, d);
@@ -624,8 +603,7 @@ public:
 		c = getColumn(2);
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount > 3)
-	void getColumns(ColumnVec& a, ColumnVec& b, ColumnVec& c, ColumnVec& d) const
+	void getColumns(ColumnVec& a, ColumnVec& b, ColumnVec& c, ColumnVec& d) const requires(kTColumnCount > 3)
 	{
 		getColumns(a, b, c);
 		d = getColumn(3);
@@ -938,8 +916,7 @@ public:
 		setColumns(xAxis, yAxis, zAxis);
 	}
 
-	ANKI_ENABLE_METHOD(kTRowCount == kTColumnCount && !kHasSimd)
-	void transpose()
+	void transpose() requires(kIsSquare && !kHasSimd)
 	{
 		for(U j = 0; j < kTRowCount; j++)
 		{
@@ -953,8 +930,7 @@ public:
 	}
 
 #if ANKI_ENABLE_SIMD
-	ANKI_ENABLE_METHOD(kTRowCount == kTColumnCount && kHasSimd)
-	void transpose()
+	void transpose() requires(kIsSquare&& kHasSimd)
 	{
 #	if ANKI_SIMD_SSE
 		_MM_TRANSPOSE4_PS(m_simd[0], m_simd[1], m_simd[2], m_simd[3]);
@@ -982,8 +958,7 @@ public:
 		}
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount == kTRowCount)
-	TMat getTransposed() const
+	TMat getTransposed() const requires(kIsSquare)
 	{
 		TMat out;
 		for(U j = 0; j < kTRowCount; j++)
@@ -996,8 +971,7 @@ public:
 		return out;
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount == 3 && kTRowCount == 3)
-	T getDet() const
+	T getDet() const requires(kSize == 9)
 	{
 		const auto& m = *this;
 		// For the accurate method see < r664
@@ -1005,8 +979,7 @@ public:
 			   + m(0, 2) * (m(0, 1) * m(2, 1) - m(1, 1) * m(2, 0));
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	T getDet() const
+	T getDet() const requires(kSize == 16)
 	{
 		const auto& t = *this;
 		return t(0, 3) * t(1, 2) * t(2, 1) * t(3, 0) - t(0, 2) * t(1, 3) * t(2, 1) * t(3, 0) - t(0, 3) * t(1, 1) * t(2, 2) * t(3, 0)
@@ -1019,8 +992,7 @@ public:
 			   - t(0, 0) * t(1, 2) * t(2, 1) * t(3, 3) - t(0, 1) * t(1, 0) * t(2, 2) * t(3, 3) + t(0, 0) * t(1, 1) * t(2, 2) * t(3, 3);
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount == 3 && kTRowCount == 3)
-	TMat getInverse() const
+	TMat getInverse() const requires(kSize == 9)
 	{
 		// Using Gramer's method Inv(A) = (1 / getDet(A)) * Adj(A)
 		const TMat& m = *this;
@@ -1052,8 +1024,7 @@ public:
 	}
 
 	/// Invert using Cramer's rule
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	TMat getInverse() const
+	TMat getInverse() const requires(kSize == 16)
 	{
 		Array<T, 12> tmp;
 		const auto& in = (*this);
@@ -1128,15 +1099,13 @@ public:
 	}
 
 	/// See getInverse
-	ANKI_ENABLE_METHOD((kTColumnCount == 4 && kTRowCount == 4) || (kTColumnCount == 3 && kTRowCount == 3))
-	void invert()
+	void invert() requires(kSize == 16 || kSize == 9)
 	{
 		(*this) = getInverse();
 	}
 
 	/// 12 muls, 27 adds. Something like m4 = m0 * m1 but without touching the 4rth row and allot faster
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	static TMat combineTransformations(const TMat& m0, const TMat& m1)
+	static TMat combineTransformations(const TMat& m0, const TMat& m1) requires(kSize == 16)
 	{
 		// See the clean code in < r664
 
@@ -1168,8 +1137,7 @@ public:
 	}
 
 	/// Create a new matrix that is equivalent to Mat4(this)*Mat4(b)
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4 && !kHasSimd)
-	TMat combineTransformations(const TMat& b) const
+	[[nodiscard]] TMat combineTransformations(const TMat& b) const requires(kSize == 12 && !kHasSimd)
 	{
 		const auto& a = *this;
 		TMat c;
@@ -1194,8 +1162,7 @@ public:
 	}
 
 #if ANKI_ENABLE_SIMD
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4 && kHasSimd)
-	TMat combineTransformations(const TMat& b) const
+	[[nodiscard]] TMat combineTransformations(const TMat& b) const requires(kSize == 12 && kHasSimd)
 	{
 		TMat c;
 		const auto& a = *this;
@@ -1241,8 +1208,7 @@ public:
 
 	/// Calculate a perspective projection matrix. The z is mapped in [0, 1] range just like DX and Vulkan.
 	/// Same as D3DXMatrixPerspectiveFovRH
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	[[nodiscard]] static TMat calculatePerspectiveProjectionMatrix(T fovX, T fovY, T near, T far)
+	[[nodiscard]] static TMat calculatePerspectiveProjectionMatrix(T fovX, T fovY, T near, T far) requires(kSize == 16)
 	{
 		ANKI_ASSERT(fovX > T(0) && fovY > T(0) && near > T(0) && far > T(0));
 		const T g = near - far;
@@ -1271,8 +1237,7 @@ public:
 
 	/// Calculate an orthographic projection matrix. The z is mapped in [0, 1] range just like DX and Vulkan.
 	/// Same as D3DXMatrixOrthoOffCenterRH.
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	[[nodiscard]] static TMat calculateOrthographicProjectionMatrix(T right, T left, T top, T bottom, T near, T far)
+	[[nodiscard]] static TMat calculateOrthographicProjectionMatrix(T right, T left, T top, T bottom, T near, T far) requires(kSize == 16)
 	{
 		ANKI_ASSERT(right != T(0) && left != T(0) && top != T(0) && bottom != T(0) && near != T(0) && far != T(0));
 		const T difx = right - left;
@@ -1310,8 +1275,7 @@ public:
 	/// Vec2 xy = ndc.xy() * unprojParams.xy() * z;
 	/// Vec3 posViewSpace(xy, z);
 	/// @endcode
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	static TVec<T, 4> calculatePerspectiveUnprojectionParams(T fovX, T fovY, T near, T far)
+	static TVec<T, 4> calculatePerspectiveUnprojectionParams(T fovX, T fovY, T near, T far) requires(kSize == 16)
 	{
 		TVec<T, 4> out;
 		const T g = near - far;
@@ -1342,8 +1306,7 @@ public:
 	}
 
 	/// Assuming this is a projection matrix extract the unprojection parameters. See calculatePerspectiveUnprojectionParams for more info.
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	TVec<T, 4> extractPerspectiveUnprojectionParams() const
+	TVec<T, 4> extractPerspectiveUnprojectionParams() const requires(kSize == 16)
 	{
 		TVec<T, 4> out;
 		const auto& m = *this;
@@ -1355,8 +1318,7 @@ public:
 	}
 
 	/// If we suppose this matrix represents a transformation, return the inverted transformation
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	TMat getInverseTransformation() const
+	TMat getInverseTransformation() const requires(kSize == 16)
 	{
 		const TMat<T, 3, 3> invertedRot = getRotationPart().getTransposed();
 		TVec<T, 3> invertedTsl = getTranslationPart().xyz();
@@ -1365,8 +1327,7 @@ public:
 	}
 
 	/// If we suppose this matrix represents a transformation, return the inverted transformation
-	ANKI_ENABLE_METHOD(kTRowCount == 3 && kTColumnCount == 4)
-	TMat getInverseTransformation() const
+	TMat getInverseTransformation() const requires(kSize == 12)
 	{
 		const TMat<T, 3, 3> invertedRot = getRotationPart().getTransposed();
 		TVec<T, 3> invertedTsl = getTranslationPart().xyz();
@@ -1375,8 +1336,7 @@ public:
 	}
 
 	/// @note 9 muls, 9 adds
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	TVec<T, 3> transform(const TVec<T, 3>& v) const
+	TVec<T, 3> transform(const TVec<T, 3>& v) const requires(kSize == 16)
 	{
 		const auto& m = *this;
 		return TVec<T, 3>(m(0, 0) * v.x() + m(0, 1) * v.y() + m(0, 2) * v.z() + m(0, 3),
@@ -1385,8 +1345,9 @@ public:
 	}
 
 	/// Create a new transform matrix position at eye and looking at refPoint.
-	template<U kVecDimensions, ANKI_ENABLE(kTRowCount == 3 && kTColumnCount == 4 && kVecDimensions >= 3)>
-	static TMat lookAt(const TVec<T, kVecDimensions>& eye, const TVec<T, kVecDimensions>& refPoint, const TVec<T, kVecDimensions>& up)
+	template<U kVecDimensions>
+	static TMat lookAt(const TVec<T, kVecDimensions>& eye, const TVec<T, kVecDimensions>& refPoint,
+					   const TVec<T, kVecDimensions>& up) requires(kTRowCount == 3 && kTColumnCount == 4 && kVecDimensions >= 3)
 	{
 		const TVec<T, 3> vdir = (refPoint.xyz() - eye.xyz()).getNormalized();
 		const TVec<T, 3> vup = (up.xyz() - vdir * up.xyz().dot(vdir)).getNormalized();
@@ -1397,8 +1358,9 @@ public:
 	}
 
 	/// Create a new transform matrix position at eye and looking at refPoint.
-	template<U kVecDimensions, ANKI_ENABLE(kTRowCount == 4 && kTColumnCount == 4 && kVecDimensions >= 3)>
-	static TMat lookAt(const TVec<T, kVecDimensions>& eye, const TVec<T, kVecDimensions>& refPoint, const TVec<T, kVecDimensions>& up)
+	template<U kVecDimensions>
+	static TMat lookAt(const TVec<T, kVecDimensions>& eye, const TVec<T, kVecDimensions>& refPoint,
+					   const TVec<T, kVecDimensions>& up) requires(kTRowCount == 4 && kTColumnCount == 4 && kVecDimensions >= 3)
 	{
 		const TVec<T, 4> vdir = (refPoint.xyz0() - eye.xyz0()).getNormalized();
 		const TVec<T, 4> vup = (up.xyz0() - vdir * up.xyz0().dot(vdir)).getNormalized();
@@ -1423,20 +1385,17 @@ public:
 		*this = getZero();
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount == 3 && kTRowCount == 3)
-	static TMat getIdentity()
+	static TMat getIdentity() requires(kSize == 9)
 	{
 		return TMat(T(1), T(0), T(0), T(0), T(1), T(0), T(0), T(0), T(1));
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 4)
-	static TMat getIdentity()
+	static TMat getIdentity() requires(kSize == 16)
 	{
 		return TMat(T(1), T(0), T(0), T(0), T(0), T(1), T(0), T(0), T(0), T(0), T(1), T(0), T(0), T(0), T(0), T(1));
 	}
 
-	ANKI_ENABLE_METHOD(kTColumnCount == 4 && kTRowCount == 3)
-	static TMat getIdentity()
+	static TMat getIdentity() requires(kSize == 12)
 	{
 		return TMat(T(1), T(0), T(0), T(0), T(0), T(1), T(0), T(0), T(0), T(0), T(1), T(0));
 	}
@@ -1451,8 +1410,7 @@ public:
 		return U8(kTColumnCount * kTRowCount);
 	}
 
-	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	String toString() const
+	String toString() const requires(std::is_floating_point<T>::value)
 	{
 		String str;
 		for(U j = 0; j < kTRowCount; ++j)

+ 1 - 2
AnKi/Math/Transform.h

@@ -226,8 +226,7 @@ public:
 		return *this;
 	}
 
-	ANKI_ENABLE_METHOD(std::is_floating_point<T>::value)
-	[[nodiscard]] String toString() const
+	[[nodiscard]] String toString() const requires(std::is_floating_point<T>::value)
 	{
 		String str;
 		String b = m_origin.toString();

Fichier diff supprimé car celui-ci est trop grand
+ 363 - 721
AnKi/Math/Vec.h


+ 2 - 3
AnKi/Renderer/Utils/GpuVisibility.cpp

@@ -560,9 +560,8 @@ void GpuVisibility::populateRenderGraph(GpuMeshletVisibilityInput& in, GpuMeshle
 	pass.newBufferDependency(mem.m_bufferDepedency, BufferUsageBit::kUavComputeWrite);
 	pass.newBufferDependency(in.m_dependency, BufferUsageBit::kIndirectCompute);
 
-	pass.setWork([this, technique = in.m_technique, hzbRt = in.m_hzbRt, viewProjMat = in.m_viewProjectionMatrix, camTrf = in.m_cameraTransform,
-				  viewportSize = in.m_viewportSize, computeIndirectArgs = in.m_taskShaderIndirectArgsBuffer, out,
-				  meshletGroupInstancesBuffer = in.m_meshletGroupInstancesBuffer,
+	pass.setWork([this, hzbRt = in.m_hzbRt, viewProjMat = in.m_viewProjectionMatrix, camTrf = in.m_cameraTransform, viewportSize = in.m_viewportSize,
+				  computeIndirectArgs = in.m_taskShaderIndirectArgsBuffer, out, meshletGroupInstancesBuffer = in.m_meshletGroupInstancesBuffer,
 				  bucketMeshletGroupInstanceRanges = in.m_bucketMeshletGroupInstanceRanges](RenderPassWorkContext& rpass) {
 		CommandBuffer& cmdb = *rpass.m_commandBuffer;
 

+ 10 - 12
AnKi/Util/Array.h

@@ -32,16 +32,16 @@ public:
 	Value m_data[kSize];
 
 	/// Access an element using an integer.
-	template<typename TInt, ANKI_ENABLE(!std::is_enum<TInt>::value)>
-	constexpr Reference operator[](const TInt n)
+	template<typename TInt>
+	constexpr Reference operator[](const TInt n) requires(!std::is_enum<TInt>::value)
 	{
 		ANKI_ASSERT(PtrSize(n) < kSize);
 		return m_data[n];
 	}
 
 	/// Access an element using an integer.
-	template<typename TInt, ANKI_ENABLE(!std::is_enum<TInt>::value)>
-	constexpr ConstReference operator[](const TInt n) const
+	template<typename TInt>
+	constexpr ConstReference operator[](const TInt n) const requires(!std::is_enum<TInt>::value)
 	{
 		ANKI_ASSERT(PtrSize(n) < kSize);
 		return m_data[n];
@@ -49,16 +49,16 @@ public:
 
 	/// Access an element using an enumerant. It's a little bit special and separate from operator[] that accepts integer. This to avoid any short of
 	/// arbitrary integer type casting.
-	template<typename TEnum, ANKI_ENABLE(std::is_enum<TEnum>::value)>
-	constexpr Reference operator[](const TEnum n)
+	template<typename TEnum>
+	constexpr Reference operator[](const TEnum n) requires(std::is_enum<TEnum>::value)
 	{
 		return operator[](typename std::underlying_type<TEnum>::type(n));
 	}
 
 	/// Access an element using an enumerant. It's a little bit special and separate from operator[] that accepts integer. This to avoid any short of
 	/// arbitrary integer type casting.
-	template<typename TEnum, ANKI_ENABLE(std::is_enum<TEnum>::value)>
-	constexpr ConstReference operator[](const TEnum n) const
+	template<typename TEnum>
+	constexpr ConstReference operator[](const TEnum n) const requires(std::is_enum<TEnum>::value)
 	{
 		return operator[](typename std::underlying_type<TEnum>::type(n));
 	}
@@ -153,8 +153,7 @@ public:
 
 	// Get size
 #define ANKI_ARRAY_SIZE_METHOD(type, condition) \
-	ANKI_ENABLE_METHOD(condition) \
-	static constexpr type getSize() \
+	static constexpr type getSize() requires(condition) \
 	{ \
 		return type(kSize); \
 	}
@@ -193,8 +192,7 @@ public:
 
 	// Get size in bytes
 #define ANKI_ARRAY_SIZE_IN_BYTES_METHOD(type, condition) \
-	ANKI_ENABLE_METHOD(condition) \
-	static constexpr type getSizeInBytes() \
+	static constexpr type getSizeInBytes() requires(condition) \
 	{ \
 		return type(kSize * sizeof(Value)); \
 	}

+ 18 - 82
AnKi/Util/Functions.h

@@ -49,70 +49,6 @@ namespace anki {
 #define ANKI_FORMAT_U32(u32) ANKI_FORMAT_U16(u32 >> 16), ANKI_FORMAT_U16(u32)
 #define ANKI_FORMAT_U64(u64) ANKI_FORMAT_U32(u64 >> 32), ANKI_FORMAT_U32(u64)
 
-// ANKI_ENABLE_METHOD & ANKI_ENABLE_ARG trickery copied from Tick library
-template<typename T, int N>
-struct DummyType
-{
-};
-
-#if defined(_MSC_VER)
-template<bool B>
-struct RequiresBool
-{
-	static constexpr bool kValue = B;
-};
-
-template<typename T, int N>
-struct RequiresUnwrap : T
-{
-};
-
-template<int N>
-struct PrivateEnum
-{
-	enum class Type
-	{
-		kNA
-	};
-};
-
-#	define ANKI_REQUIRES_BOOL(line, ...) RequiresUnwrap<decltype(RequiresBool<(__VA_ARGS__)>{}), line>::kValue
-
-#	define ANKI_ENABLE_INTERNAL(line, ...) \
-		typename PrivateEnum<line>::Type ANKI_CONCATENATE( \
-			privateEnum, line) = PrivateEnum<line>::Type::kNA, \
-						 bool ANKI_CONCATENATE(privateBool, line) = true, \
-						 typename = typename std::enable_if_t<(ANKI_CONCATENATE(privateBool, line) && ANKI_REQUIRES_BOOL(line, __VA_ARGS__))>
-#else
-
-#	define ANKI_ENABLE_INTERNAL(line, ...) bool privateBool##line = true, typename std::enable_if_t<(privateBool##line && __VA_ARGS__), int> = 0
-
-#endif
-
-/// Use it to enable a method based on a constant expression.
-/// @code
-/// template<int N> class Foo {
-/// 	ANKI_ENABLE_METHOD(N == 10)
-/// 	void foo() {}
-///	};
-/// @endcode
-#define ANKI_ENABLE_METHOD(...) template<ANKI_ENABLE_INTERNAL(__LINE__, __VA_ARGS__)>
-
-/// Use it to enable a method based on a constant expression.
-/// @code
-/// class Foo {
-/// 	void foo(ANKI_ENABLE_ARG(Boo, expr) b) {}
-///	};
-/// @endcode
-#define ANKI_ENABLE_ARG(type_, expression) typename std::conditional<(expression), type_, DummyType<type_, __LINE__>>::type
-
-/// Use it to enable a method based on a constant expression.
-/// @code
-/// template<typename T, ANKI_ENABLE(std::is_whatever<T>::value)>
-/// void foo(T x) {}
-/// @endcode
-#define ANKI_ENABLE(...) ANKI_ENABLE_INTERNAL(__LINE__, __VA_ARGS__)
-
 /// OS specific debug breakpoint
 #if ANKI_OS_WINDOWS
 #	define ANKI_DEBUG_BREAK() __debugbreak()
@@ -124,16 +60,16 @@ struct PrivateEnum
 U64 getRandom();
 
 /// Pick a random number from min to max
-template<typename T, ANKI_ENABLE(std::is_floating_point<T>::value)>
-T getRandomRange(T min, T max)
+template<typename T>
+T getRandomRange(T min, T max) requires(std::is_floating_point<T>::value)
 {
 	ANKI_ASSERT(min <= max);
 	const F64 r = F64(getRandom()) / F64(kMaxU64);
 	return T(min + r * (max - min));
 }
 
-template<typename T, ANKI_ENABLE(std::is_integral<T>::value)>
-T getRandomRange(T min, T max)
+template<typename T>
+T getRandomRange(T min, T max) requires(std::is_integral<T>::value)
 {
 	ANKI_ASSERT(min <= max);
 	const U64 r = getRandom();
@@ -155,15 +91,15 @@ inline constexpr T max(T a, T b)
 }
 
 /// Check if a number is a power of 2
-template<typename Int, ANKI_ENABLE(std::is_integral<Int>::value)>
-inline constexpr Bool isPowerOfTwo(Int x)
+template<typename Int>
+inline constexpr Bool isPowerOfTwo(Int x) requires(std::is_integral<Int>::value)
 {
 	return !(x == 0) && !(x & (x - 1));
 }
 
 /// Get the next power of two number. For example if x is 130 this will return 256.
-template<typename Int, ANKI_ENABLE(std::is_integral<Int>::value)>
-inline constexpr Int nextPowerOfTwo(Int x)
+template<typename Int>
+inline constexpr Int nextPowerOfTwo(Int x) requires(std::is_integral<Int>::value)
 {
 	const F64 d = F64(x);
 	const F64 res = pow(2.0, ceil(log(d) / log(2.0)));
@@ -171,8 +107,8 @@ inline constexpr Int nextPowerOfTwo(Int x)
 }
 
 /// Get the previous power of two number. For example if x is 130 this will return 128.
-template<typename Int, ANKI_ENABLE(std::is_integral<Int>::value)>
-inline constexpr Int previousPowerOfTwo(Int x)
+template<typename Int>
+inline constexpr Int previousPowerOfTwo(Int x) requires(std::is_integral<Int>::value)
 {
 	const U64 out = (x != 0) ? (1_U64 << ((sizeof(U64) * 8 - 1) - __builtin_clzll(x))) : 0;
 	return Int(out);
@@ -181,8 +117,8 @@ inline constexpr Int previousPowerOfTwo(Int x)
 /// Get the aligned number rounded up.
 /// @param alignment The bytes of alignment
 /// @param value The value to align
-template<typename TInt, ANKI_ENABLE(std::is_integral<TInt>::value)>
-inline constexpr TInt getAlignedRoundUp(PtrSize alignment, TInt value)
+template<typename TInt>
+inline constexpr TInt getAlignedRoundUp(PtrSize alignment, TInt value) requires(std::is_integral<TInt>::value)
 {
 	ANKI_ASSERT(alignment > 0);
 	PtrSize v = PtrSize(value);
@@ -193,8 +129,8 @@ inline constexpr TInt getAlignedRoundUp(PtrSize alignment, TInt value)
 /// Get the aligned number rounded up.
 /// @param alignment The bytes of alignment
 /// @param value The value to align
-template<typename TFloat, ANKI_ENABLE(std::is_floating_point<TFloat>::value)>
-inline constexpr TFloat getAlignedRoundUp(TFloat alignment, TFloat value)
+template<typename TFloat>
+inline constexpr TFloat getAlignedRoundUp(TFloat alignment, TFloat value) requires(std::is_floating_point<TFloat>::value)
 {
 	ANKI_ASSERT(alignment > TFloat(0.0));
 	return ceil(value / alignment) * alignment;
@@ -212,8 +148,8 @@ inline void alignRoundUp(TAlignment alignment, TValue& value)
 /// Get the aligned number rounded down.
 /// @param alignment The bytes of alignment
 /// @param value The value to align
-template<typename TInt, ANKI_ENABLE(std::is_integral<TInt>::value)>
-inline constexpr TInt getAlignedRoundDown(PtrSize alignment, TInt value)
+template<typename TInt>
+inline constexpr TInt getAlignedRoundDown(PtrSize alignment, TInt value) requires(std::is_integral<TInt>::value)
 {
 	ANKI_ASSERT(alignment > 0);
 	PtrSize v = PtrSize(value);
@@ -224,8 +160,8 @@ inline constexpr TInt getAlignedRoundDown(PtrSize alignment, TInt value)
 /// Get the aligned number rounded down.
 /// @param alignment The bytes of alignment
 /// @param value The value to align
-template<typename TFloat, ANKI_ENABLE(std::is_floating_point<TFloat>::value)>
-inline constexpr TFloat getAlignedRoundDown(TFloat alignment, TFloat value)
+template<typename TFloat>
+inline constexpr TFloat getAlignedRoundDown(TFloat alignment, TFloat value) requires(std::is_floating_point<TFloat>::value)
 {
 	ANKI_ASSERT(alignment > TFloat(0.0));
 	return floor(value / alignment) * alignment;

+ 8 - 8
AnKi/Util/Serializer.h

@@ -104,8 +104,8 @@ public:
 	}
 
 	/// Write an array of complex values. Can't call this directly.
-	template<typename T, ANKI_ENABLE(!_ANKI_SIMPLE_TYPE)>
-	void doArray([[maybe_unused]] CString varName, PtrSize memberOffset, const T* arr, PtrSize size)
+	template<typename T>
+	void doArray([[maybe_unused]] CString varName, PtrSize memberOffset, const T* arr, PtrSize size) requires(!_ANKI_SIMPLE_TYPE)
 	{
 		if(!m_err)
 		{
@@ -114,9 +114,9 @@ public:
 	}
 
 	/// Write an array of int or float types. Can't call this directly.
-	template<typename T, ANKI_ENABLE(_ANKI_SIMPLE_TYPE)>
+	template<typename T>
 	void doArray([[maybe_unused]] CString varName, [[maybe_unused]] PtrSize memberOffset, [[maybe_unused]] const T* arr,
-				 [[maybe_unused]] PtrSize size)
+				 [[maybe_unused]] PtrSize size) requires(_ANKI_SIMPLE_TYPE)
 	{
 		// Do nothing, it's already copied
 	}
@@ -129,8 +129,8 @@ public:
 	}
 
 	/// Write a dynamic array of complex types. Can't call this directly.
-	template<typename T, ANKI_ENABLE(!_ANKI_SIMPLE_TYPE)>
-	void doDynamicArray([[maybe_unused]] CString varName, PtrSize memberOffset, const T* arr, PtrSize size)
+	template<typename T>
+	void doDynamicArray([[maybe_unused]] CString varName, PtrSize memberOffset, const T* arr, PtrSize size) requires(!_ANKI_SIMPLE_TYPE)
 	{
 		if(!m_err)
 		{
@@ -139,8 +139,8 @@ public:
 	}
 
 	/// Write a dynamic array of int and float values. Can't call this directly.
-	template<typename T, ANKI_ENABLE(_ANKI_SIMPLE_TYPE)>
-	void doDynamicArray([[maybe_unused]] CString varName, PtrSize memberOffset, const T* arr, PtrSize size)
+	template<typename T>
+	void doDynamicArray([[maybe_unused]] CString varName, PtrSize memberOffset, const T* arr, PtrSize size) requires(_ANKI_SIMPLE_TYPE)
 	{
 		if(!m_err)
 		{

+ 1 - 1
AnKi/Util/Tracer.cpp

@@ -92,7 +92,7 @@ Tracer::Chunk& Tracer::getOrCreateChunk(ThreadLocal& tlocal)
 	return *out;
 }
 
-TracerEventHandle Tracer::beginEvent(const char* eventName)
+TracerEventHandle Tracer::beginEvent([[maybe_unused]] const char* eventName)
 {
 	TracerEventHandle out;
 

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff