Jelajahi Sumber

Make constructor not horrible... a runtime checked constructor is just asking for trouble.

Sam Jaffe 7 tahun lalu
induk
melakukan
f2c81d83c8

+ 9 - 11
vector.hpp

@@ -66,14 +66,6 @@ VECTOR_ENABLE_IF_LT_N(i, value_type &) name() { return _data[i]; }
     // Constructors
     vector() = default;
     
-    vector(std::initializer_list<T> && init) {
-      expects(init.size() == N, "initializer size mismatch");
-      std::size_t idx = 0;
-      for ( auto it = init.begin(), end = init.end(); it != end && idx < N; ++it, ++idx ) {
-        _data[idx] = *it;
-      }
-    }
-    
     vector(std::array<T, N> const & init) {
       VECTOR_FOR_EACH(i) { _data[i] = init[i]; }
     }
@@ -231,15 +223,15 @@ VECTOR_ENABLE_IF_LT_N(i, value_type &) name() { return _data[i]; }
     }
     
     VECTOR_ENABLE_IF_EQ_N(3, T, N) cross(vector const & other) const {
-      return {
+      return {{
         y()*other.z() - z()*other.y(),
         z()*other.x() - x()*other.z(),
         x()*other.y() - y()*other.x()
-      };
+      }};
     }
     
     VECTOR_ENABLE_IF_EQ_N(2, T, 3) cross(vector const & other) const {
-      return { 0, 0, x()*other.y() - y()*other.x() };
+      return {{ 0, 0, x()*other.y() - y()*other.x() }};
     }
     
     vector<mag_t, N> projection(vector const & other) const {
@@ -282,4 +274,10 @@ VECTOR_ENABLE_IF_LT_N(i, value_type &) name() { return _data[i]; }
   bool operator>=(vector<T, N> const & lhs, vector<T, N> const & rhs) { return compare(lhs, rhs) >= 0; }
 } }
 
+template <typename... Ts>
+auto make_vector(Ts && ...elems) -> math::vector::vector<typename std::common_type<Ts...>::type, sizeof...(Ts)> {
+  return {{elems...}};
+}
+
+
 using math::vector::abs;

+ 2 - 0
vector.xcodeproj/xcuserdata/samjaffe.xcuserdatad/xcschemes/xcschememanagement.plist

@@ -6,6 +6,8 @@
 	<dict>
 		<key>vector.xcscheme</key>
 		<dict>
+			<key>isShown</key>
+			<false/>
 			<key>orderHint</key>
 			<integer>39</integer>
 		</dict>

+ 29 - 26
vector_test.cpp

@@ -24,22 +24,17 @@ using vec4i = math::vector::vector<int, 4>;
 vec2i iota2i() { return iota<int, 2>(); }
 vec3i iota3i() { return iota<int, 3>(); }
 
-TEST(Vector, IncompatibleSizeThrows) {
-  EXPECT_THROW((vec2i{1}), std::logic_error);
-  EXPECT_THROW((vec2i{1,1,1}), std::logic_error);
-}
-
 TEST(Vector, Equality) {
-  EXPECT_THAT((iota3i()), (vec3i{1, 2, 3}));
-  EXPECT_THAT((iota3i()), ::testing::Not(vec3i{0, 2, 3}));
+  EXPECT_THAT((iota3i()), (vec3i{{1, 2, 3}}));
+  EXPECT_THAT((iota3i()), ::testing::Not(vec3i{{0, 2, 3}}));
 }
 
 TEST(Vector, DefaultConstructorIsAllZero) {
-  EXPECT_THAT(vec3i(), (vec3i{0,0,0}));
+  EXPECT_THAT(vec3i(), (vec3i{{0,0,0}}));
 }
 
 TEST(Vector, ExtensionConstructorAppendsZeros) {
-  EXPECT_THAT(vec4i(iota3i()), (vec4i{1,2,3,0}));
+  EXPECT_THAT(vec4i(iota3i()), (vec4i{{1,2,3,0}}));
 }
 
 TEST(Vector, CanAccessVectorElements) {
@@ -54,32 +49,32 @@ TEST(Vector, AccessingOutOfRangeThrows) {
 }
 
 TEST(Vector, CrossProduct2DHasOnlyZElement) {
-  EXPECT_THAT((vec2i{1,1}.cross(vec2i{-1,1})), (vec3i{0,0,2}));
+  EXPECT_THAT((vec2i{{1,1}}.cross(vec2i{{-1,1}})), (vec3i{{0,0,2}}));
 }
 
 TEST(Vector, CrossProduct3DHasAllElements) {
-  EXPECT_THAT((vec3i{1,1,2}.cross(vec3i{-1,1,1})), (vec3i{-1,-3,2}));
+  EXPECT_THAT((vec3i{{1,1,2}}.cross(vec3i{{-1,1,1}})), (vec3i{{-1,-3,2}}));
 }
 
 TEST(Vector, AdditionIsPiecewise) {
-  EXPECT_THAT((vec2i{1,0} + vec2i{0,1}), (vec2i{1,1}));
+  EXPECT_THAT((vec2i{{1,0}} + vec2i{{0,1}}), (vec2i{{1,1}}));
 }
 
 TEST(Vector, SubtractionIsPiecewise) {
-  EXPECT_THAT((vec2i{1,0} - vec2i{0,1}), (vec2i{1,-1}));
+  EXPECT_THAT((vec2i{{1,0}} - vec2i{{0,1}}), (vec2i{{1,-1}}));
 }
 
 TEST(Vector, MultiplicationIsPiecewise) {
-  EXPECT_THAT((vec2i{1,0}*(vec2i{2,1})), (vec2i{2,0}));
+  EXPECT_THAT((vec2i{{1,0}}*(vec2i{{2,1}})), (vec2i{{2,0}}));
 }
 
 TEST(Vector, DivisionIsPiecewise) {
-  EXPECT_THAT((vec2i{6,4}/(vec2i{2,1})), (vec2i{3,4}));
+  EXPECT_THAT((vec2i{{6,4}}/(vec2i{{2,1}})), (vec2i{{3,4}}));
 }
 
 TEST(Vector, DivisionByZeroThrowsException) {
   EXPECT_THROW(vec3{} / 0, std::domain_error);
-  EXPECT_THROW((vec3{1.0, 1.0, 1.0}/(vec3{1.0, 0.5, 0.0})), std::domain_error);
+  EXPECT_THROW((vec3{{1.0, 1.0, 1.0}}/(vec3{{1.0, 0.5, 0.0}})), std::domain_error);
 }
 
 //  TEST(Vector, AdditionWithValueType) {
@@ -93,12 +88,12 @@ TEST(Vector, DivisionByZeroThrowsException) {
 //  }
 
 TEST(Vector, MultiplicationWithValueType) {
-  EXPECT_THAT((vec2i{1,0} * 3), (vec2i{3,0}));
-  EXPECT_THAT(2*iota2i(), (vec2i{2,4}));
+  EXPECT_THAT((vec2i{{1,0}} * 3), (vec2i{{3,0}}));
+  EXPECT_THAT(2*iota2i(), (vec2i{{2,4}}));
 }
 
 TEST(Vector, DivisionWithValueType) {
-  EXPECT_THAT((vec2i{6,4} / 2), (vec2i{3,2}));
+  EXPECT_THAT((vec2i{{6,4}} / 2), (vec2i{{3,2}}));
 //  EXPECT_THAT(4/iota2i(), (vec2i{4,2}));
 }
 
@@ -110,17 +105,17 @@ TEST(Vector, Length) {
 
 TEST(Vector, Distance) {
   //    EXPECT_THAT((iota3i().distanceSquared(vec3i{3, 1, -1})), 21);
-  EXPECT_THAT((iota3i() - vec3i{3, 1, -1}).magnitude(),
+  EXPECT_THAT((iota3i() - vec3i{{3, 1, -1}}).magnitude(),
               ::testing::DoubleNear(std::sqrt(21), 0.00001));
 }
 
 TEST(Vector, Projection) {
-  EXPECT_THAT((iota3i().projection(vec3i{3, 1, -1})).magnitude(),
+  EXPECT_THAT((iota3i().projection(vec3i{{3, 1, -1}})).magnitude(),
               ::testing::DoubleNear(std::sqrt(4.0/11.0), 0.00001));
 }
 
 TEST(Vector, DotProductIsSumOfElementProducts) {
-  EXPECT_THAT((iota3i().dot(vec3i{3, 0, -1})), 0);
+  EXPECT_THAT((iota3i().dot(vec3i{{3, 0, -1}})), 0);
 }
 
 TEST(Vector, UnitFunctionCreatesNewVectorOverMagnitude) {
@@ -132,22 +127,30 @@ TEST(Vector, UnitFunctionCreatesNewVectorOverMagnitude) {
 }
 
 TEST(Vector, CanCastEntireVectorThroughConstructor) {
-  EXPECT_THAT((vec3i(vec3{1.0, 2.3, 3.9})), iota3i());
+  EXPECT_THAT((vec3i(vec3{{1.0, 2.3, 3.9}})), iota3i());
 }
 
 TEST(Vector, SwapExchangesAllValues) {
   using std::swap;
-  vec2i a{1, 2}; const vec2i ac = a;
-  vec2i b{5, 7}; const vec2i bc = b;
+  vec2i a{{1, 2}}; const vec2i ac = a;
+  vec2i b{{5, 7}}; const vec2i bc = b;
   swap(a, b);
   EXPECT_THAT(a, bc);
   EXPECT_THAT(b, ac);
 }
 
 TEST(Vector, UnaryNegateOperatorNegatesAllElements) {
-  EXPECT_THAT(-iota3i(), (vec3i{-1,-2,-3}));
+  EXPECT_THAT(-iota3i(), (vec3i{{-1,-2,-3}}));
 }
 
 TEST(Vector, AbsoluteValueOfVectorAbsAllElements) {
   EXPECT_THAT(iota3i(), abs(-iota3i()));
 }
+
+TEST(Vector, MakeVectorAllowsConstuctionFromVariadicComponents) {
+  EXPECT_TRUE((std::is_same<vec2i, decltype(make_vector(1, 2))>::value));
+  EXPECT_THAT(iota2i(), make_vector(1, 2));
+  EXPECT_FALSE((std::is_same<vec2i, decltype(make_vector(1, 2, 3))>::value));
+  EXPECT_TRUE((std::is_same<vec3i, decltype(make_vector(1, 2, 3))>::value));
+  EXPECT_THAT(iota3i(), make_vector(1, 2, 3));
+}