2 Commits 96af2c47da ... b0b890d54f

Author SHA1 Message Date
  namark b0b890d54f this is posix now so why still no work?? 5 months ago
  namark 1f3f9b678b Enabled implicit conversions for vector. 5 months ago
3 changed files with 62 additions and 7 deletions
  1. 33 6
      source/simple/geom/vector.hpp
  2. 1 1
      unit_tests/Makefile
  3. 28 0
      unit_tests/point.cpp

+ 33 - 6
source/simple/geom/vector.hpp

@@ -268,8 +268,19 @@ namespace simple::geom
 			&& !std::is_same<Another, vector>::value
 			&& !std::is_base_of<vector, Another>::value
 			&& std::is_convertible<typename Another::coordinate_type, Coordinate>::value
+			&& std::is_constructible<Coordinate, typename Another::coordinate_type>::value
 		>* = nullptr>
-		struct is_convertible_to_me {};
+		struct is_implicitly_convertible_to_me {};
+
+		template <typename Another, std::enable_if_t<
+			Another::dimensions == Dimensions
+			&& !std::is_same<Another, vector>::value
+			&& !std::is_base_of<vector, Another>::value
+			&& !std::is_convertible<typename Another::coordinate_type, Coordinate>::value
+			// TODO: this does not cover aggregates and enums
+			&& std::is_constructible<Coordinate, typename Another::coordinate_type>::value
+		>* = nullptr>
+		struct is_explicitly_convertible_to_me {};
 
 		template <typename Another, size_t dimension = Dimensions - 1>
 		constexpr void set_in_order(const Another& another)
@@ -290,24 +301,40 @@ namespace simple::geom
 			: raw {std::forward<Coordinates>(coordinates)...}
 		{}
 
-		// TODO: since operators follow promotion rules of underlying type now, it might be more sensible to make construction/conversions do that too
-		// TODO: constexpr and forwarding
-		template <typename Another, is_convertible_to_me<Another>* = nullptr,
+		// TODO: forwarding
+		template <typename Another, is_explicitly_convertible_to_me<Another>* = nullptr,
 		std::enable_if_t<std::is_same_v<typename Another::order, Order>> *...>
 		constexpr explicit vector(const Another& another) : raw{}
 		{
 			for(size_t i = 0; i < Dimensions; ++i)
-				raw[i] = another[i];
+				raw[i] = Coordinate(another[i]);
 		}
 
 		// TODO: forwarding
-		template <typename Another, is_convertible_to_me<Another>* = nullptr,
+		template <typename Another, is_explicitly_convertible_to_me<Another>* = nullptr,
 		std::enable_if_t<!std::is_same_v<typename Another::order, Order>> *...>
 		constexpr explicit vector(const Another& another) : raw{}
 		{
 			set_in_order<Another>(another);
 		}
 
+		// TODO: forwarding
+		template <typename Another, is_implicitly_convertible_to_me<Another>* = nullptr,
+		std::enable_if_t<std::is_same_v<typename Another::order, Order>> *...>
+		constexpr vector(const Another& another) : raw{}
+		{
+			for(size_t i = 0; i < Dimensions; ++i)
+				raw[i] = another[i];
+		}
+
+		// TODO: forwarding
+		template <typename Another, is_implicitly_convertible_to_me<Another>* = nullptr,
+		std::enable_if_t<!std::is_same_v<typename Another::order, Order>> *...>
+		constexpr vector(const Another& another) : raw{}
+		{
+			set_in_order<Another>(another);
+		}
+
 		explicit constexpr vector(const array & coordinates) : raw(coordinates)
 		{
 		}

+ 1 - 1
unit_tests/Makefile

@@ -12,7 +12,7 @@ OCTAVE	:= octave
 
 $(TEMPDIR)/vector.run: matrix.data square_matrix.data matrix_vector.data dot_product.data
 
-ifneq ($(shell command -v $(OCTAVE)),)
+ifneq ($(shell command -v $(OCTAVE) 2> /dev/null),)
 %.data: %.octave
 	$(OCTAVE) -q $< | sed 's/[ABans=]//g' > $@
 endif

+ 28 - 0
unit_tests/point.cpp

@@ -81,6 +81,33 @@ void OtherConstruction()
 	static_assert(int4(-1,1,-1,-1) == int4::unit<1>(1,-1), "");
 }
 
+bool is_int3(vector<char, 3>) { return false; }
+bool is_int3(vector<int, 3>) { return true; }
+
+struct char_constructible
+{
+	char a;
+	char_constructible() {}
+	explicit char_constructible(char a): a(a) {}
+	bool operator==(char o) const { return o == a; };
+};
+
+void ImplicitConversion()
+{
+	vector<char,3> c {'a','b','c'};
+	vector<int,3> i{};
+	i = c;
+	assert(( i == vector{int('a'), int('b'), int('c')} ));
+	assert(( i == vector{'a', 'b', 'c'} ));
+	assert(( is_int3(i) ));
+	assert(( not is_int3(c) ));
+
+	vector<char_constructible, 3> b{};
+	// b = c; // TODO: need no-compile tests
+	b = vector<char_constructible,3>{c};
+	assert(( b == vector{'a', 'b', 'c'} ));
+}
+
 void Transformation()
 {
 	float4 p {1.3f, 1.5f, 2.1f, 4.6f};
@@ -740,6 +767,7 @@ int main()
 	ZeroConstruction();
 	EqualityComparison();
 	OtherConstruction();
+	ImplicitConversion();
 	Transformation();
 	Mixing();
 	MultidimensionalElementAccess();