Browse Source

Added find first set.

Branimir Karadžić 2 years ago
parent
commit
610a2e468d
3 changed files with 25 additions and 0 deletions
  1. 7 0
      include/bx/inline/uint32_t.inl
  2. 5 0
      include/bx/uint32_t.h
  3. 13 0
      tests/uint32_test.cpp

+ 7 - 0
include/bx/inline/uint32_t.inl

@@ -453,6 +453,13 @@ namespace bx
 	template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int32_t  _val) { return              uint32_cnttz<uint32_t>(_val);   }
 	template<> inline BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(int64_t  _val) { return              uint32_cnttz<uint64_t>(_val);   }
 
+	template<typename Ty>
+	inline BX_CONSTEXPR_FUNC uint32_t uint32_ffs(Ty _x)
+	{
+		return Ty(0) == _x ? uint32_t(0) : uint32_cnttz<Ty>(_x) + 1;
+	}
+
+
 	inline BX_CONSTEXPR_FUNC uint32_t uint32_part1by1(uint32_t _a)
 	{
 		// shuffle:

+ 5 - 0
include/bx/uint32_t.h

@@ -162,6 +162,11 @@ namespace bx
 	template<typename Ty>
 	BX_CONSTEXPR_FUNC uint32_t uint32_cnttz(Ty _val);
 
+	/// Find first set.
+	///
+	template<typename Ty>
+	BX_CONSTEXPR_FUNC uint32_t uint32_ffs(Ty _val);
+
 	///
 	BX_CONSTEXPR_FUNC uint32_t uint32_part1by1(uint32_t _a);
 

+ 13 - 0
tests/uint32_test.cpp

@@ -53,6 +53,19 @@ TEST_CASE("uint32_cnt", "[uint32_t]")
 	REQUIRE(63 == bx::uint32_cntlz<uint64_t>(1) );
 	REQUIRE(64 == bx::uint32_cntlz<uint64_t>(0) );
 
+	REQUIRE( 1 == bx::uint32_ffs<uint8_t >(1) );
+	REQUIRE( 8 == bx::uint32_ffs<uint8_t >(1<<7) );
+	REQUIRE( 0 == bx::uint32_ffs<uint8_t >(0) );
+	REQUIRE( 2 == bx::uint32_ffs<uint8_t >(0x3e) );
+	REQUIRE( 1 == bx::uint32_ffs<uint16_t>(1) );
+	REQUIRE(16 == bx::uint32_ffs<uint16_t>(1<<15) );
+	REQUIRE( 0 == bx::uint32_ffs<uint16_t>(0) );
+	REQUIRE( 1 == bx::uint32_ffs<uint32_t>(1) );
+	REQUIRE( 0 == bx::uint32_ffs<uint32_t>(0) );
+	REQUIRE(32 == bx::uint32_ffs<uint32_t>(1u<<31) );
+	REQUIRE( 1 == bx::uint32_ffs<uint64_t>(1) );
+	REQUIRE( 0 == bx::uint32_ffs<uint64_t>(0) );
+
 	REQUIRE( 0 == bx::uint32_cntbits(0) );
 	REQUIRE( 1 == bx::uint32_cntbits(1) );