Бранимир Караџић 4 年之前
父节点
当前提交
2eee001125
共有 4 个文件被更改,包括 126 次插入36 次删除
  1. 82 17
      include/bx/bx.h
  2. 19 9
      include/bx/inline/bx.inl
  3. 10 10
      src/bx.cpp
  4. 15 0
      tests/crt_test.cpp

+ 82 - 17
include/bx/bx.h

@@ -31,10 +31,13 @@
 
 
 namespace bx
 namespace bx
 {
 {
+	/// Used to return successful execution of a program code.
 	constexpr int32_t kExitSuccess = 0;
 	constexpr int32_t kExitSuccess = 0;
+
+	/// Used to return unsuccessful execution of a program code.
 	constexpr int32_t kExitFailure = 1;
 	constexpr int32_t kExitFailure = 1;
 
 
-	///
+	/// Returns true if type `Ty` is trivially copyable / POD type.
 	template<class Ty>
 	template<class Ty>
 	constexpr bool isTriviallyCopyable();
 	constexpr bool isTriviallyCopyable();
 
 
@@ -42,6 +45,10 @@ namespace bx
 	template <class Ty>
 	template <class Ty>
 	Ty* addressOf(Ty& _a);
 	Ty* addressOf(Ty& _a);
 
 
+	/// Find the address of an object of a class that has an overloaded unary ampersand (&) operator.
+	template <class Ty>
+	const Ty* addressOf(const Ty& _a);
+
 	/// Swap two values.
 	/// Swap two values.
 	template<typename Ty>
 	template<typename Ty>
 	void swap(Ty& _a, Ty& _b);
 	void swap(Ty& _a, Ty& _b);
@@ -57,23 +64,23 @@ namespace bx
 	template<typename Ty>
 	template<typename Ty>
 	constexpr Ty max(const Ty& _a, const Ty& _b);
 	constexpr Ty max(const Ty& _a, const Ty& _b);
 
 
-	/// Returns minimum of three values.
-	template<typename Ty>
-	constexpr Ty min(const Ty& _a, const Ty& _b, const Ty& _c);
+	/// Returns minimum of three or more values.
+	template<typename Ty, typename... Args>
+	constexpr Ty min(const Ty& _a, const Ty& _b, const Args&... _args);
 
 
-	/// Returns maximum of three values.
-	template<typename Ty>
-	constexpr Ty max(const Ty& _a, const Ty& _b, const Ty& _c);
+	/// Returns maximum of three or more values.
+	template<typename Ty, typename... Args>
+	constexpr Ty max(const Ty& _a, const Ty& _b, const Args&... _args);
 
 
-	/// Returns middle of three values.
-	template<typename Ty>
-	constexpr Ty mid(const Ty& _a, const Ty& _b, const Ty& _c);
+	/// Returns middle of three or more values.
+	template<typename Ty, typename... Args>
+	constexpr Ty mid(const Ty& _a, const Ty& _b, const Args&... _args);
 
 
 	/// Returns clamped value between min/max.
 	/// Returns clamped value between min/max.
 	template<typename Ty>
 	template<typename Ty>
 	constexpr Ty clamp(const Ty& _a, const Ty& _min, const Ty& _max);
 	constexpr Ty clamp(const Ty& _a, const Ty& _min, const Ty& _max);
 
 
-	/// Returns true if value is power of 2.
+	/// Returns true if value `_a` is power of 2.
 	template<typename Ty>
 	template<typename Ty>
 	constexpr bool isPowerOf2(Ty _a);
 	constexpr bool isPowerOf2(Ty _a);
 
 
@@ -94,7 +101,7 @@ namespace bx
 	/// @param _src Source pointer.
 	/// @param _src Source pointer.
 	/// @param _srcStride Source stride.
 	/// @param _srcStride Source stride.
 	/// @param _stride Number of bytes per stride to copy.
 	/// @param _stride Number of bytes per stride to copy.
-	/// @param _num Number of strides.
+	/// @param _numStrides Number of strides.
 	///
 	///
 	/// @remark Source and destination memory blocks must not overlap.
 	/// @remark Source and destination memory blocks must not overlap.
 	///
 	///
@@ -104,12 +111,31 @@ namespace bx
 		, const void* _src
 		, const void* _src
 		, uint32_t _srcStride
 		, uint32_t _srcStride
 		, uint32_t _stride
 		, uint32_t _stride
-		, uint32_t _num
+		, uint32_t _numStrides
 		);
 		);
 
 
+	/// Copy memory block.
+	///
+	/// @param _dst Destination pointer.
+	/// @param _src Source pointer.
+	/// @param _numBytes Number of bytes to copy.
+	///
+	/// @remark If source and destination memory blocks overlap memory will be copied in reverse
+	///   order.
 	///
 	///
 	void memMove(void* _dst, const void* _src, size_t _numBytes);
 	void memMove(void* _dst, const void* _src, size_t _numBytes);
 
 
+	/// Copy strided memory block.
+	///
+	/// @param _dst Destination pointer.
+	/// @param _dstStride Destination stride.
+	/// @param _src Source pointer.
+	/// @param _srcStride Source stride.
+	/// @param _stride Number of bytes per stride to copy.
+	/// @param _numStrides Number of strides.
+	///
+	/// @remark If source and destination memory blocks overlap memory will be copied in reverse
+	///   order.
 	///
 	///
 	void memMove(
 	void memMove(
 		  void* _dst
 		  void* _dst
@@ -117,34 +143,73 @@ namespace bx
 		, const void* _src
 		, const void* _src
 		, uint32_t _srcStride
 		, uint32_t _srcStride
 		, uint32_t _stride
 		, uint32_t _stride
-		, uint32_t _num
+		, uint32_t _numStrides
 		);
 		);
 
 
+	/// Fill memory block to specified value `_ch`.
+	///
+	/// @param _dst Destination pointer.
+	/// @param _ch Fill value.
+	/// @param _numBytes Number of bytes to copy.
 	///
 	///
 	void memSet(void* _dst, uint8_t _ch, size_t _numBytes);
 	void memSet(void* _dst, uint8_t _ch, size_t _numBytes);
 
 
+	/// Fill strided memory block to specified value `_ch`.
 	///
 	///
-	void memSet(void* _dst, uint32_t _dstStride, uint8_t _ch, uint32_t _stride, uint32_t _num);
+	/// @param _dst Destination pointer.
+	/// @param _dstStride Destination stride.
+	/// @param _ch Fill value.
+	/// @param _stride Number of bytes per stride to copy.
+	/// @param _numStrides Number of strides.
+	///
+	void memSet(
+		  void* _dst
+		, uint32_t _dstStride
+		, uint8_t _ch
+		, uint32_t _stride
+		, uint32_t _numStrides
+		);
 
 
+	/// Compare two memory blocks.
+	///
+	/// @param _lhs Pointer to memory block.
+	/// @param _rhs Pointer to memory block.
+	/// @param _numBytes Number of bytes to compare.
+	///
+	/// @returns 0 if two blocks are identical, positive value if first different byte in `_lhs` is
+	///   greater than corresponding byte in `_rhs`.
 	///
 	///
 	int32_t memCmp(const void* _lhs, const void* _rhs, size_t _numBytes);
 	int32_t memCmp(const void* _lhs, const void* _rhs, size_t _numBytes);
 
 
+	/// Gather data scattered throught memory into linear memory block.
+	///
+	/// @param _dst Destination pointer.
+	/// @param _src Source pointer.
+	/// @param _stride Number of bytes per stride to copy.
+	/// @param _numStrides Number of strides.
 	///
 	///
 	void gather(
 	void gather(
 		  void* _dst
 		  void* _dst
 		, const void* _src
 		, const void* _src
 		, uint32_t _srcStride
 		, uint32_t _srcStride
 		, uint32_t _stride
 		, uint32_t _stride
-		, uint32_t _num
+		, uint32_t _numStrides
 		);
 		);
 
 
+	/// Scatter data from linear memory block through memory.
+	///
+	/// @param _dst Destination pointer.
+	/// @param _dstStride Destination stride.
+	/// @param _src Source pointer.
+	/// @param _stride Number of bytes per stride to copy.
+	/// @param _numStrides Number of strides.
 	///
 	///
 	void scatter(
 	void scatter(
 		  void* _dst
 		  void* _dst
 		, uint32_t _dstStride
 		, uint32_t _dstStride
 		, const void* _src
 		, const void* _src
 		, uint32_t _stride
 		, uint32_t _stride
-		, uint32_t _num
+		, uint32_t _numStrides
 		);
 		);
 
 
 } // namespace bx
 } // namespace bx

+ 19 - 9
include/bx/inline/bx.inl

@@ -43,6 +43,16 @@ namespace bx
 			);
 			);
 	}
 	}
 
 
+	template<class Ty>
+	inline const Ty* addressOf(const Ty& _a)
+	{
+		return reinterpret_cast<const Ty*>(
+				&const_cast<char&>(
+					reinterpret_cast<const volatile char&>(_a)
+				)
+			);
+	}
+
 	template<typename Ty>
 	template<typename Ty>
 	inline void swap(Ty& _a, Ty& _b)
 	inline void swap(Ty& _a, Ty& _b)
 	{
 	{
@@ -61,22 +71,22 @@ namespace bx
 		return _a > _b ? _a : _b;
 		return _a > _b ? _a : _b;
 	}
 	}
 
 
-	template<typename Ty>
-	inline constexpr Ty min(const Ty& _a, const Ty& _b, const Ty& _c)
+	template<typename Ty, typename... Args>
+	inline constexpr Ty min(const Ty& _a, const Ty& _b, const Args&... _args)
 	{
 	{
-		return min(min(_a, _b), _c);
+		return min(min(_a, _b), _args...);
 	}
 	}
 
 
-	template<typename Ty>
-	inline constexpr Ty max(const Ty& _a, const Ty& _b, const Ty& _c)
+	template<typename Ty, typename... Args>
+	inline constexpr Ty max(const Ty& _a, const Ty& _b, const Args&... _args)
 	{
 	{
-		return max(max(_a, _b), _c);
+		return max(max(_a, _b), _args...);
 	}
 	}
 
 
-	template<typename Ty>
-	inline constexpr Ty mid(const Ty& _a, const Ty& _b, const Ty& _c)
+	template<typename Ty, typename... Args>
+	inline constexpr Ty mid(const Ty& _a, const Ty& _b, const Args&... _args)
 	{
 	{
-		return max(min(_a, _b), min(max(_a, _b), _c) );
+		return max(min(_a, _b), min(max(_a, _b), _args...) );
 	}
 	}
 
 
 	template<typename Ty>
 	template<typename Ty>

+ 10 - 10
src/bx.cpp

@@ -50,20 +50,20 @@ namespace bx
 		, const void* _src
 		, const void* _src
 		, uint32_t _srcStride
 		, uint32_t _srcStride
 		, uint32_t _stride
 		, uint32_t _stride
-		, uint32_t _num
+		, uint32_t _numStrides
 		)
 		)
 	{
 	{
 		if (_stride == _srcStride
 		if (_stride == _srcStride
 		&&  _stride == _dstStride)
 		&&  _stride == _dstStride)
 		{
 		{
-			memCopy(_dst, _src, _stride*_num);
+			memCopy(_dst, _src, _stride*_numStrides);
 			return;
 			return;
 		}
 		}
 
 
 		const uint8_t* src = (const uint8_t*)_src;
 		const uint8_t* src = (const uint8_t*)_src;
 		      uint8_t* dst = (uint8_t*)_dst;
 		      uint8_t* dst = (uint8_t*)_dst;
 
 
-		for (uint32_t ii = 0; ii < _num; ++ii, src += _srcStride, dst += _dstStride)
+		for (uint32_t ii = 0; ii < _numStrides; ++ii, src += _srcStride, dst += _dstStride)
 		{
 		{
 			memCopy(dst, src, _stride);
 			memCopy(dst, src, _stride);
 		}
 		}
@@ -108,20 +108,20 @@ namespace bx
 		, const void* _src
 		, const void* _src
 		, uint32_t _srcStride
 		, uint32_t _srcStride
 		, uint32_t _stride
 		, uint32_t _stride
-		, uint32_t _num
+		, uint32_t _numStrides
 		)
 		)
 	{
 	{
 		if (_stride == _srcStride
 		if (_stride == _srcStride
 		&&  _stride == _dstStride)
 		&&  _stride == _dstStride)
 		{
 		{
-			memMove(_dst, _src, _stride*_num);
+			memMove(_dst, _src, _stride*_numStrides);
 			return;
 			return;
 		}
 		}
 
 
 		const uint8_t* src = (const uint8_t*)_src;
 		const uint8_t* src = (const uint8_t*)_src;
 		      uint8_t* dst = (uint8_t*)_dst;
 		      uint8_t* dst = (uint8_t*)_dst;
 
 
-		for (uint32_t ii = 0; ii < _num; ++ii, src += _srcStride, dst += _dstStride)
+		for (uint32_t ii = 0; ii < _numStrides; ++ii, src += _srcStride, dst += _dstStride)
 		{
 		{
 			memMove(dst, src, _stride);
 			memMove(dst, src, _stride);
 		}
 		}
@@ -186,15 +186,15 @@ namespace bx
 	}
 	}
 
 
 	///
 	///
-	void gather(void* _dst, const void* _src, uint32_t _srcStride, uint32_t _stride, uint32_t _num)
+	void gather(void* _dst, const void* _src, uint32_t _srcStride, uint32_t _stride, uint32_t _numStrides)
 	{
 	{
-		memMove(_dst, _stride, _src, _srcStride, _stride, _num);
+		memMove(_dst, _stride, _src, _srcStride, _stride, _numStrides);
 	}
 	}
 
 
 	///
 	///
-	void scatter(void* _dst, uint32_t _dstStride, const void* _src, uint32_t _stride, uint32_t _num)
+	void scatter(void* _dst, uint32_t _dstStride, const void* _src, uint32_t _stride, uint32_t _numStrides)
 	{
 	{
-		memMove(_dst, _dstStride, _src, _stride, _num, _stride);
+		memMove(_dst, _dstStride, _src, _stride, _stride, _numStrides);
 	}
 	}
 
 
 } // namespace bx
 } // namespace bx

+ 15 - 0
tests/crt_test.cpp

@@ -41,3 +41,18 @@ TEST_CASE("memMove", "")
 	bx::memSet(str, 'x', 4);
 	bx::memSet(str, 'x', 4);
 	REQUIRE(0 == bx::memCmp(str, orignal, 9) );
 	REQUIRE(0 == bx::memCmp(str, orignal, 9) );
 }
 }
+
+TEST_CASE("scatter/gather", "")
+{
+	const char* str = "a\0b\0v\0g\0d";
+
+	char tmp0[64];
+	bx::gather(tmp0, str, 2, 1, 5);
+	REQUIRE(0 == bx::memCmp(tmp0, "abvgd", 5) );
+
+	char tmp1[64];
+	bx::scatter(tmp1, 2, tmp0, 1, 5);
+	bx::memSet(&tmp1[1], 2, 0, 1, 5);
+	REQUIRE(0 == bx::memCmp(tmp1, str, 5) );
+
+}