Przeglądaj źródła

refactor: change implementation to use non-variadic ctor

Sam Jaffe 1 rok temu
rodzic
commit
a918330ac9

+ 61 - 0
include/math/vector/macro.h

@@ -0,0 +1,61 @@
+//
+//  macro.h
+//  vector
+//
+//  Created by Sam Jaffe on 2/17/24.
+//
+
+// Utility Macros
+#define COMMA() ,
+
+#define DEFER_RESOLUTION template <bool _ = true>
+
+#define DEFERRED_ENABLE_IF_T(B, ...) std::enable_if_t<B && _, ##__VA_ARGS__>
+
+#define DEFERRED_ENABLE_IF(B, ...)                                             \
+  DEFER_RESOLUTION DEFERRED_ENABLE_IF_T(B, ##__VA_ARGS__)
+
+// Repetition Macros for Trivial Codegen
+#define REPEAT0(X, div, ...)
+#define REPEAT1(X, div, ...) X(0, ##__VA_ARGS__)
+#define REPEAT2(X, div, ...)                                                   \
+  REPEAT1(X, div, ##__VA_ARGS__) div() X(1, ##__VA_ARGS__)
+#define REPEAT3(X, div, ...)                                                   \
+  REPEAT2(X, div, ##__VA_ARGS__) div() X(2, ##__VA_ARGS__)
+#define REPEAT4(X, div, ...)                                                   \
+  REPEAT3(X, div, ##__VA_ARGS__) div() X(3, ##__VA_ARGS__)
+#define REPEAT5(X, div, ...)                                                   \
+  REPEAT4(X, div, ##__VA_ARGS__) div() X(4, ##__VA_ARGS__)
+
+#define REPEAT(N, X, div, ...) REPEAT##N(X, div, ##__VA_ARGS__)
+
+#define ARGN(N, ...) __VA_ARGS__ arg##N
+
+// Vector Concept Macros
+#define VECTOR_ENABLE_IF_LT_N(index, expr)                                     \
+  DEFERRED_ENABLE_IF(std::size_t(index) < N, expr)
+
+#define VECTOR_ENABLE_IF_EQ_N(index, t, n)                                     \
+  DEFERRED_ENABLE_IF(std::size_t(index) == N, vector<t, n>)
+
+#define VECTOR_ENABLE_IF_EQ_T(_type, t, n)                                     \
+  std::enable_if_t<std::is_same_v<_type, t>, vector<t, n>>
+
+#define VECTOR_DISABLE_IF_VECTOR(_type, t, n)                                  \
+  std::enable_if_t<!is_vector_v<_type>, vector<t, n>>
+
+// Vector Access/Iteration Macros
+#define VECTOR_ACCESS_FN(name, i)                                              \
+  VECTOR_ENABLE_IF_LT_N(i, value_type const &) name() const {                  \
+    return _data[i];                                                           \
+  }                                                                            \
+  VECTOR_ENABLE_IF_LT_N(i, value_type &) name() { return _data[i]; }
+
+#define VECTOR_FOR_EACH_RANGE(var, end)                                        \
+  for (std::size_t var = 0; var < end; ++var)
+#define VECTOR_FOR_EACH(var) VECTOR_FOR_EACH_RANGE(var, N)
+
+#define VECTOR_CTOR_N_ARGS(N_IN)                                               \
+  DEFER_RESOLUTION vector(REPEAT(N_IN, ARGN, COMMA, T),                        \
+                          DEFERRED_ENABLE_IF_T(N_IN == N, bool) = true)        \
+      : vector(std::array{REPEAT(N_IN, ARGN, COMMA)})

+ 1 - 0
include/math/vector/traits.hpp

@@ -15,4 +15,5 @@ struct is_vector<matrix::matrix<T, R, C>> {
   static const constexpr bool value = true;
 };
 
+template <typename T> constexpr bool is_vector_v = is_vector<T>::value;
 }

+ 30 - 0
include/math/vector/undef.h

@@ -0,0 +1,30 @@
+//
+//  undef.h
+//  vector
+//
+//  Created by Sam Jaffe on 2/17/24.
+//
+
+#undef VECTOR_ENABLE_IF_LT_N
+#undef VECTOR_ENABLE_IF_EQ_N
+#undef VECTOR_ENABLE_IF_EQ_T
+#undef VECTOR_DISABLE_IF_VECTOR
+
+#undef VECTOR_ACCESS_FN
+#undef VECTOR_FOR_EACH_RANGE
+#undef VECTOR_FOR_EACH
+#undef VECTOR_CTOR_N_ARGS
+
+#undef ARGN
+#undef REPEAT
+#undef REPEAT0
+#undef REPEAT1
+#undef REPEAT2
+#undef REPEAT3
+#undef REPEAT4
+#undef REPEAT5
+
+#undef COMMA
+#undef DEFER_RESOLUTION
+#undef DEFERRED_ENABLE_IF_T
+#undef DEFERRED_ENABLE_IF

+ 7 - 30
include/math/vector/vector.hpp

@@ -19,32 +19,9 @@
 #include <expect/expect.hpp>
 
 #include "math/vector/forward.h"
+#include "math/vector/macro.h"
 #include "math/vector/traits.hpp"
 
-#define VECTOR_ENABLE_IF_LT_N(index, expr)                                     \
-  template <bool _ = true>                                                     \
-  typename std::enable_if<std::size_t(index) < N && _, expr>::type
-
-#define VECTOR_ENABLE_IF_EQ_N(index, t, n)                                     \
-  template <bool _ = true>                                                     \
-  typename std::enable_if<std::size_t(index) == N && _, vector<t, n>>::type
-
-#define VECTOR_ENABLE_IF_EQ_T(_type, t, n)                                     \
-  typename std::enable_if<std::is_same<_type, t>::value, vector<t, n>>::type
-
-#define VECTOR_DISABLE_IF_VECTOR(_type, t, n)                                  \
-  typename std::enable_if<!is_vector<_type>::value, vector<t, n>>::type
-
-#define VECTOR_ACCESS_FN(name, i)                                              \
-  VECTOR_ENABLE_IF_LT_N(i, value_type const &) name() const {                  \
-    return _data[i];                                                           \
-  }                                                                            \
-  VECTOR_ENABLE_IF_LT_N(i, value_type &) name() { return _data[i]; }
-
-#define VECTOR_FOR_EACH_RANGE(var, end)                                        \
-  for (std::size_t var = 0; var < end; ++var)
-#define VECTOR_FOR_EACH(var) VECTOR_FOR_EACH_RANGE(var, N)
-
 namespace math::vector {
 
 template <typename T, std::size_t N> class vector {
@@ -62,12 +39,10 @@ public:
   // Constructors
   vector() = default;
 
-  template <typename... Us> vector(T arg0, Us... args) {
-    static_assert(std::is_same_v<std::common_type_t<T, Us...>, T>,
-                  "must be type compatible");
-    static_assert(sizeof...(Us) + 1 == N, "size mismatch");
-    *this = vector(std::array<T, N>{arg0, static_cast<T>(args)...});
-  }
+  VECTOR_CTOR_N_ARGS(1) {}
+  VECTOR_CTOR_N_ARGS(2) {}
+  VECTOR_CTOR_N_ARGS(3) {}
+  VECTOR_CTOR_N_ARGS(4) {}
 
   vector(std::array<T, N> const & init) {
     VECTOR_FOR_EACH(i) { _data[i] = init[i]; }
@@ -294,3 +269,5 @@ bool operator>=(vector<T, N> const & lhs, vector<T, N> const & rhs) {
 }
 
 using math::vector::abs;
+
+#include "math/vector/undef.h"

+ 74 - 69
vector.xcodeproj/project.pbxproj

@@ -41,48 +41,34 @@
 			remoteGlobalIDString = 05818F901A685AEA0072A469;
 			remoteInfo = GoogleMockTests;
 		};
-		CDAE63E12B77D9C000551FB8 /* PBXContainerItemProxy */ = {
+		CDCA9BBD2B78587500C8B1EC /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
-			containerPortal = CDAE62592B77B93600551FB8 /* expect.xcodeproj */;
+			containerPortal = CDCA9BB72B78587500C8B1EC /* expect.xcodeproj */;
+			proxyType = 2;
+			remoteGlobalIDString = CDD476BD29C5423B00BDB829;
+			remoteInfo = expect;
+		};
+		CDCA9BBF2B78587500C8B1EC /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = CDCA9BB72B78587500C8B1EC /* expect.xcodeproj */;
 			proxyType = 2;
 			remoteGlobalIDString = CDEC1E8A235248390091D9F2;
 			remoteInfo = "expect-test";
 		};
-		CDAE63E92B77D9FF00551FB8 /* PBXContainerItemProxy */ = {
+		CDCA9BC72B78587900C8B1EC /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
-			containerPortal = CDAE63E32B77D9FF00551FB8 /* test-helpers.xcodeproj */;
+			containerPortal = CDCA9BC12B78587900C8B1EC /* test-helpers.xcodeproj */;
 			proxyType = 2;
 			remoteGlobalIDString = CD6030FC2AF67772000D9F31;
 			remoteInfo = "test-helpers";
 		};
-		CDAE63EB2B77D9FF00551FB8 /* PBXContainerItemProxy */ = {
+		CDCA9BC92B78587900C8B1EC /* PBXContainerItemProxy */ = {
 			isa = PBXContainerItemProxy;
-			containerPortal = CDAE63E32B77D9FF00551FB8 /* test-helpers.xcodeproj */;
+			containerPortal = CDCA9BC12B78587900C8B1EC /* test-helpers.xcodeproj */;
 			proxyType = 2;
 			remoteGlobalIDString = CDD965FA2B654D090091D92C;
 			remoteInfo = "test-helpers-test";
 		};
-		CDAE63ED2B77DA1B00551FB8 /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = CDAE63E32B77D9FF00551FB8 /* test-helpers.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = CD6030FB2AF67772000D9F31;
-			remoteInfo = "test-helpers";
-		};
-		CDC7D1CB2B77DA6F0034C06F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = CDAE62592B77B93600551FB8 /* expect.xcodeproj */;
-			proxyType = 1;
-			remoteGlobalIDString = CDD476BC29C5423B00BDB829;
-			remoteInfo = expect;
-		};
-		CDC7D1CF2B77DA6F0034C06F /* PBXContainerItemProxy */ = {
-			isa = PBXContainerItemProxy;
-			containerPortal = CDAE62592B77B93600551FB8 /* expect.xcodeproj */;
-			proxyType = 2;
-			remoteGlobalIDString = CDD476BD29C5423B00BDB829;
-			remoteInfo = expect;
-		};
 /* End PBXContainerItemProxy section */
 
 /* Begin PBXFileReference section */
@@ -92,8 +78,13 @@
 		CD10425C24E837FB00C0DF2A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		CD10426824E8701100C0DF2A /* math */ = {isa = PBXFileReference; lastKnownFileType = folder; name = math; path = include/math; sourceTree = "<group>"; };
 		CDAE62452B77B8A800551FB8 /* libvector.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libvector.a; sourceTree = BUILT_PRODUCTS_DIR; };
-		CDAE62592B77B93600551FB8 /* expect.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = expect.xcodeproj; path = extern/expect/expect.xcodeproj; sourceTree = "<group>"; };
-		CDAE63E32B77D9FF00551FB8 /* test-helpers.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "test-helpers.xcodeproj"; path = "extern/test-helpers/test-helpers.xcodeproj"; sourceTree = "<group>"; };
+		CDB6F8BA2B80EFEC00FE3226 /* vector.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = vector.hpp; sourceTree = "<group>"; };
+		CDB6F8BB2B80EFEC00FE3226 /* traits.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = traits.hpp; sourceTree = "<group>"; };
+		CDB6F8BC2B80EFEC00FE3226 /* forward.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = forward.h; sourceTree = "<group>"; };
+		CDB6F8C52B80EFFB00FE3226 /* macro.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = macro.h; sourceTree = "<group>"; };
+		CDB6F8C62B80F21900FE3226 /* undef.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = undef.h; sourceTree = "<group>"; };
+		CDCA9BB72B78587500C8B1EC /* expect.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = expect.xcodeproj; path = external/expect/expect.xcodeproj; sourceTree = "<group>"; };
+		CDCA9BC12B78587900C8B1EC /* test-helpers.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "test-helpers.xcodeproj"; path = "external/test-helpers/test-helpers.xcodeproj"; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 
 /* Begin PBXFrameworksBuildPhase section */
@@ -118,10 +109,11 @@
 		0E5DFDD01BB4D3360063976E = {
 			isa = PBXGroup;
 			children = (
-				CDAE62592B77B93600551FB8 /* expect.xcodeproj */,
-				CDAE63E32B77D9FF00551FB8 /* test-helpers.xcodeproj */,
+				CDCA9BB72B78587500C8B1EC /* expect.xcodeproj */,
+				CDCA9BC12B78587900C8B1EC /* test-helpers.xcodeproj */,
 				CD0C597A20C31CC300454F82 /* GoogleMock.xcodeproj */,
 				CD10426824E8701100C0DF2A /* math */,
+				CDB6F8B72B80EFEC00FE3226 /* include */,
 				CD10423524E836A700C0DF2A /* test */,
 				CD10425924E837FB00C0DF2A /* vector-test */,
 				0E5DFDF41BB4D5040063976E /* Products */,
@@ -172,20 +164,48 @@
 			name = Frameworks;
 			sourceTree = "<group>";
 		};
-		CDAE63DE2B77D9C000551FB8 /* Products */ = {
+		CDB6F8B72B80EFEC00FE3226 /* include */ = {
+			isa = PBXGroup;
+			children = (
+				CDB6F8B82B80EFEC00FE3226 /* math */,
+			);
+			path = include;
+			sourceTree = "<group>";
+		};
+		CDB6F8B82B80EFEC00FE3226 /* math */ = {
 			isa = PBXGroup;
 			children = (
-				CDC7D1D02B77DA6F0034C06F /* libexpect.a */,
-				CDAE63E22B77D9C000551FB8 /* expect-test.xctest */,
+				CDB6F8B92B80EFEC00FE3226 /* vector */,
+			);
+			path = math;
+			sourceTree = "<group>";
+		};
+		CDB6F8B92B80EFEC00FE3226 /* vector */ = {
+			isa = PBXGroup;
+			children = (
+				CDB6F8BA2B80EFEC00FE3226 /* vector.hpp */,
+				CDB6F8BB2B80EFEC00FE3226 /* traits.hpp */,
+				CDB6F8BC2B80EFEC00FE3226 /* forward.h */,
+				CDB6F8C52B80EFFB00FE3226 /* macro.h */,
+				CDB6F8C62B80F21900FE3226 /* undef.h */,
+			);
+			path = vector;
+			sourceTree = "<group>";
+		};
+		CDCA9BB82B78587500C8B1EC /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				CDCA9BBE2B78587500C8B1EC /* libexpect.a */,
+				CDCA9BC02B78587500C8B1EC /* expect-test.xctest */,
 			);
 			name = Products;
 			sourceTree = "<group>";
 		};
-		CDAE63E42B77D9FF00551FB8 /* Products */ = {
+		CDCA9BC22B78587900C8B1EC /* Products */ = {
 			isa = PBXGroup;
 			children = (
-				CDAE63EA2B77D9FF00551FB8 /* libtest-helpers.a */,
-				CDAE63EC2B77D9FF00551FB8 /* test-helpers-test.xctest */,
+				CDCA9BC82B78587900C8B1EC /* libtest-helpers.a */,
+				CDCA9BCA2B78587900C8B1EC /* test-helpers-test.xctest */,
 			);
 			name = Products;
 			sourceTree = "<group>";
@@ -214,7 +234,6 @@
 			buildRules = (
 			);
 			dependencies = (
-				CDAE63EE2B77DA1B00551FB8 /* PBXTargetDependency */,
 			);
 			name = "vector-test";
 			productName = "vector-test";
@@ -233,7 +252,6 @@
 			buildRules = (
 			);
 			dependencies = (
-				CDC7D1CC2B77DA6F0034C06F /* PBXTargetDependency */,
 			);
 			name = vector;
 			productName = vector;
@@ -271,16 +289,16 @@
 			projectDirPath = "";
 			projectReferences = (
 				{
-					ProductGroup = CDAE63DE2B77D9C000551FB8 /* Products */;
-					ProjectRef = CDAE62592B77B93600551FB8 /* expect.xcodeproj */;
+					ProductGroup = CDCA9BB82B78587500C8B1EC /* Products */;
+					ProjectRef = CDCA9BB72B78587500C8B1EC /* expect.xcodeproj */;
 				},
 				{
 					ProductGroup = CD0C597B20C31CC300454F82 /* Products */;
 					ProjectRef = CD0C597A20C31CC300454F82 /* GoogleMock.xcodeproj */;
 				},
 				{
-					ProductGroup = CDAE63E42B77D9FF00551FB8 /* Products */;
-					ProjectRef = CDAE63E32B77D9FF00551FB8 /* test-helpers.xcodeproj */;
+					ProductGroup = CDCA9BC22B78587900C8B1EC /* Products */;
+					ProjectRef = CDCA9BC12B78587900C8B1EC /* test-helpers.xcodeproj */;
 				},
 			);
 			projectRoot = "";
@@ -320,32 +338,32 @@
 			remoteRef = CD0C598720C31CC300454F82 /* PBXContainerItemProxy */;
 			sourceTree = BUILT_PRODUCTS_DIR;
 		};
-		CDAE63E22B77D9C000551FB8 /* expect-test.xctest */ = {
+		CDCA9BBE2B78587500C8B1EC /* libexpect.a */ = {
+			isa = PBXReferenceProxy;
+			fileType = archive.ar;
+			path = libexpect.a;
+			remoteRef = CDCA9BBD2B78587500C8B1EC /* PBXContainerItemProxy */;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+		CDCA9BC02B78587500C8B1EC /* expect-test.xctest */ = {
 			isa = PBXReferenceProxy;
 			fileType = wrapper.cfbundle;
 			path = "expect-test.xctest";
-			remoteRef = CDAE63E12B77D9C000551FB8 /* PBXContainerItemProxy */;
+			remoteRef = CDCA9BBF2B78587500C8B1EC /* PBXContainerItemProxy */;
 			sourceTree = BUILT_PRODUCTS_DIR;
 		};
-		CDAE63EA2B77D9FF00551FB8 /* libtest-helpers.a */ = {
+		CDCA9BC82B78587900C8B1EC /* libtest-helpers.a */ = {
 			isa = PBXReferenceProxy;
 			fileType = archive.ar;
 			path = "libtest-helpers.a";
-			remoteRef = CDAE63E92B77D9FF00551FB8 /* PBXContainerItemProxy */;
+			remoteRef = CDCA9BC72B78587900C8B1EC /* PBXContainerItemProxy */;
 			sourceTree = BUILT_PRODUCTS_DIR;
 		};
-		CDAE63EC2B77D9FF00551FB8 /* test-helpers-test.xctest */ = {
+		CDCA9BCA2B78587900C8B1EC /* test-helpers-test.xctest */ = {
 			isa = PBXReferenceProxy;
 			fileType = wrapper.cfbundle;
 			path = "test-helpers-test.xctest";
-			remoteRef = CDAE63EB2B77D9FF00551FB8 /* PBXContainerItemProxy */;
-			sourceTree = BUILT_PRODUCTS_DIR;
-		};
-		CDC7D1D02B77DA6F0034C06F /* libexpect.a */ = {
-			isa = PBXReferenceProxy;
-			fileType = archive.ar;
-			path = libexpect.a;
-			remoteRef = CDC7D1CF2B77DA6F0034C06F /* PBXContainerItemProxy */;
+			remoteRef = CDCA9BC92B78587900C8B1EC /* PBXContainerItemProxy */;
 			sourceTree = BUILT_PRODUCTS_DIR;
 		};
 /* End PBXReferenceProxy section */
@@ -399,19 +417,6 @@
 		};
 /* End PBXSourcesBuildPhase section */
 
-/* Begin PBXTargetDependency section */
-		CDAE63EE2B77DA1B00551FB8 /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = "test-helpers";
-			targetProxy = CDAE63ED2B77DA1B00551FB8 /* PBXContainerItemProxy */;
-		};
-		CDC7D1CC2B77DA6F0034C06F /* PBXTargetDependency */ = {
-			isa = PBXTargetDependency;
-			name = expect;
-			targetProxy = CDC7D1CB2B77DA6F0034C06F /* PBXContainerItemProxy */;
-		};
-/* End PBXTargetDependency section */
-
 /* Begin XCBuildConfiguration section */
 		0E5DFDD21BB4D3360063976E /* Debug */ = {
 			isa = XCBuildConfiguration;