mirror of
https://github.com/bolero-MURAKAMI/Sprout.git
synced 2024-12-23 21:25:49 +00:00
add popcount, clz, ctz
This commit is contained in:
parent
ee8c952d05
commit
3500d0d49c
8 changed files with 181 additions and 38 deletions
52
sprout/bit/clz.hpp
Normal file
52
sprout/bit/clz.hpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
#ifndef SPROUT_BIT_CLZ_HPP
|
||||
#define SPROUT_BIT_CLZ_HPP
|
||||
|
||||
#include <climits>
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
# if SPROUT_USE_BUILTIN_BIT_OPERATION
|
||||
inline SPROUT_CONSTEXPR int
|
||||
clz(unsigned n) {
|
||||
return __builtin_clz(n);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR int
|
||||
clz(unsigned long n) {
|
||||
return __builtin_clzl(n);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR int
|
||||
clz(unsigned long long n) {
|
||||
return __builtin_clzll(n);
|
||||
}
|
||||
# endif
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
clz_impl(T n, T m = T(1) << (CHAR_BIT * sizeof(T) - 1)) {
|
||||
return m == 0 || n & m ? 0
|
||||
: 1 + sprout::detail::clz_impl(n, static_cast<T>(m >> 1))
|
||||
;
|
||||
}
|
||||
template<typename T, typename sprout::enabler_if<std::is_unsigned<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
clz(T n) {
|
||||
return sprout::detail::clz_impl(static_cast<T>(n));
|
||||
}
|
||||
template<typename T, typename sprout::enabler_if<std::is_signed<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
clz(T n) {
|
||||
return sprout::detail::clz(static_cast<typename std::make_unsigned<T>::type>(n));
|
||||
}
|
||||
} // namespace detail
|
||||
//
|
||||
// clz
|
||||
//
|
||||
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
clz(T n) {
|
||||
return sprout::detail::clz(n);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_BIT_CLZ_HPP
|
46
sprout/bit/ctz.hpp
Normal file
46
sprout/bit/ctz.hpp
Normal file
|
@ -0,0 +1,46 @@
|
|||
#ifndef SPROUT_BIT_CTZ_HPP
|
||||
#define SPROUT_BIT_CTZ_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
# if SPROUT_USE_BUILTIN_BIT_OPERATION
|
||||
inline SPROUT_CONSTEXPR int
|
||||
ctz(unsigned n) {
|
||||
return __builtin_ctz(n);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR int
|
||||
ctz(unsigned long n) {
|
||||
return __builtin_ctzl(n);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR int
|
||||
ctz(unsigned long long n) {
|
||||
return __builtin_ctzll(n);
|
||||
}
|
||||
# endif
|
||||
template<typename T, typename sprout::enabler_if<std::is_unsigned<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
ctz(T n) {
|
||||
return n & 1 ? 0
|
||||
: 1 + sprout::detail::ctz(static_cast<T>(n >> 1))
|
||||
;
|
||||
}
|
||||
template<typename T, typename sprout::enabler_if<std::is_signed<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
ctz(T n) {
|
||||
return sprout::detail::ctz(static_cast<typename std::make_unsigned<T>::type>(n));
|
||||
}
|
||||
} // namespace detail
|
||||
//
|
||||
// ctz
|
||||
//
|
||||
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
ctz(T n) {
|
||||
return sprout::detail::ctz(n);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_BIT_CTZ_HPP
|
9
sprout/bit/operation.hpp
Normal file
9
sprout/bit/operation.hpp
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef SPROUT_BIT_OPERATION_HPP
|
||||
#define SPROUT_BIT_OPERATION_HPP
|
||||
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/bit/popcount.hpp>
|
||||
#include <sprout/bit/clz.hpp>
|
||||
#include <sprout/bit/ctz.hpp>
|
||||
|
||||
#endif // #ifndef SPROUT_BIT_OPERATION_HPP
|
47
sprout/bit/popcount.hpp
Normal file
47
sprout/bit/popcount.hpp
Normal file
|
@ -0,0 +1,47 @@
|
|||
#ifndef SPROUT_BIT_POPCOUNT_HPP
|
||||
#define SPROUT_BIT_POPCOUNT_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <sprout/config.hpp>
|
||||
#include <sprout/type_traits/enabler_if.hpp>
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
# if SPROUT_USE_BUILTIN_BIT_OPERATION
|
||||
inline SPROUT_CONSTEXPR int
|
||||
popcount(unsigned n) {
|
||||
return __builtin_popcount(n);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR int
|
||||
popcount(unsigned long n) {
|
||||
return __builtin_popcountl(n);
|
||||
}
|
||||
inline SPROUT_CONSTEXPR int
|
||||
popcount(unsigned long long n) {
|
||||
return __builtin_popcountll(n);
|
||||
}
|
||||
# endif
|
||||
template<typename T, typename sprout::enabler_if<std::is_unsigned<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
popcount(T n) {
|
||||
return n == 0 ? 0
|
||||
: 1 + sprout::detail::popcount(static_cast<T>(n & (n - 1)))
|
||||
;
|
||||
}
|
||||
template<typename T, typename sprout::enabler_if<std::is_signed<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
popcount(T n) {
|
||||
return sprout::detail::popcount(static_cast<typename std::make_unsigned<T>::type>(n));
|
||||
}
|
||||
} // namespace detail
|
||||
//
|
||||
// popcount
|
||||
//
|
||||
template<typename T, typename sprout::enabler_if<std::is_integral<T>::value>::type = sprout::enabler>
|
||||
inline SPROUT_CONSTEXPR int
|
||||
popcount(T n) {
|
||||
return sprout::detail::popcount(n);
|
||||
}
|
||||
} // namespace sprout
|
||||
|
||||
#endif // #ifndef SPROUT_BIT_POPCOUNT_HPP
|
|
@ -15,42 +15,12 @@
|
|||
#include <sprout/algorithm/fixed/fill.hpp>
|
||||
#include <sprout/operation/fixed/set.hpp>
|
||||
#include <sprout/utility/forward.hpp>
|
||||
#include <sprout/bit/operation.hpp>
|
||||
#include HDR_ALGORITHM_SSCRISK_CEL_OR_SPROUT
|
||||
#include HDR_NUMERIC_SSCRISK_CEL_OR_SPROUT
|
||||
#include HDR_FUNCTIONAL_SSCRISK_CEL_OR_SPROUT
|
||||
|
||||
namespace sprout {
|
||||
namespace detail {
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
popcount(T n) {
|
||||
return n == 0 ? 0
|
||||
: 1 + sprout::detail::popcount(n & (n - 1))
|
||||
;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
clz_impl(T n, T m = 1 << (CHAR_BIT * sizeof(T))) {
|
||||
return m == 0 || n & m ? 0
|
||||
: 1 + sprout::detail::clz_impl(n, m >> 1)
|
||||
;
|
||||
}
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
clz(T n) {
|
||||
return sprout::detail::clz_impl(n >> 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline SPROUT_CONSTEXPR std::size_t
|
||||
ctz(T n) {
|
||||
return n & 1 ? 0
|
||||
: 1 + sprout::detail::ctz(n >> 1)
|
||||
;
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
namespace detail {
|
||||
struct base_bitset_from_words_construct_tag {};
|
||||
|
||||
|
@ -92,7 +62,7 @@ namespace sprout {
|
|||
public:
|
||||
SPROUT_CONSTEXPR std::size_t
|
||||
operator()(std::size_t lhs, std::size_t rhs) const SPROUT_NOEXCEPT {
|
||||
return lhs + sprout::detail::popcount(rhs);
|
||||
return lhs + sprout::popcount(rhs);
|
||||
}
|
||||
};
|
||||
public:
|
||||
|
@ -123,7 +93,7 @@ namespace sprout {
|
|||
{
|
||||
return first == last ? not_found
|
||||
: *first != static_cast<word_type>(0)
|
||||
? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::detail::ctz(*first)
|
||||
? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::ctz(*first)
|
||||
: find_first_impl(not_found, first + 1, last, i + 1)
|
||||
;
|
||||
}
|
||||
|
@ -135,14 +105,14 @@ namespace sprout {
|
|||
{
|
||||
return first == last ? not_found
|
||||
: *first != static_cast<word_type>(0)
|
||||
? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::detail::ctz(*first)
|
||||
? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::ctz(*first)
|
||||
: find_next_impl_2(not_found, first + 1, last)
|
||||
;
|
||||
}
|
||||
SPROUT_CONSTEXPR std::size_t
|
||||
find_next_impl_1(std::size_t not_found, std::size_t i, word_type thisword) const SPROUT_NOEXCEPT {
|
||||
return thisword != static_cast<word_type>(0)
|
||||
? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::detail::ctz(thisword)
|
||||
? i * (CHAR_BIT * sizeof(unsigned long)) + sprout::ctz(thisword)
|
||||
: find_next_impl_2(not_found, begin() + (i + 1), end(), i + 1)
|
||||
;
|
||||
}
|
||||
|
@ -512,7 +482,7 @@ namespace sprout {
|
|||
private:
|
||||
SPROUT_CONSTEXPR std::size_t
|
||||
find_next_impl(std::size_t prev, std::size_t not_found, word_type x) const SPROUT_NOEXCEPT {
|
||||
return x != 0 ? sprout::detail::ctz(x) + prev
|
||||
return x != 0 ? sprout::ctz(x) + prev
|
||||
: not_found
|
||||
;
|
||||
}
|
||||
|
@ -641,7 +611,7 @@ namespace sprout {
|
|||
}
|
||||
SPROUT_CONSTEXPR std::size_t
|
||||
do_count() const SPROUT_NOEXCEPT {
|
||||
return sprout::detail::popcount(w_);
|
||||
return sprout::popcount(w_);
|
||||
}
|
||||
|
||||
SPROUT_CONSTEXPR unsigned long
|
||||
|
@ -655,7 +625,7 @@ namespace sprout {
|
|||
|
||||
SPROUT_CONSTEXPR std::size_t
|
||||
find_first(std::size_t not_found) const SPROUT_NOEXCEPT {
|
||||
return w_ != 0 ? sprout::detail::ctz(w_)
|
||||
return w_ != 0 ? sprout::ctz(w_)
|
||||
: not_found
|
||||
;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,15 @@
|
|||
# endif // #ifdef SPROUT_HAS_CONSTEXPR_CMATH_FUNCTION
|
||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION
|
||||
|
||||
//
|
||||
// SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION
|
||||
//
|
||||
#ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION
|
||||
# ifndef SPROUT_HAS_CONSTEXPR_BIT_OPERATION
|
||||
# define SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION
|
||||
# endif // #ifdef SPROUT_HAS_CONSTEXPR_BIT_OPERATION
|
||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION
|
||||
|
||||
//
|
||||
// SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION
|
||||
// SPROUT_CONFIG_SUPPORT_TEMPORARY_CONTAINER_ITERATION
|
||||
|
|
|
@ -25,4 +25,8 @@
|
|||
# define SPROUT_HAS_CONSTEXPR_CMATH_FUNCTION
|
||||
#endif
|
||||
|
||||
#if ((__GNUC__ >= 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) && defined(__GXX_EXPERIMENTAL_CXX0X__))
|
||||
# define SPROUT_HAS_CONSTEXPR_BIT_OPERATION
|
||||
#endif
|
||||
|
||||
#endif // #ifndef SPROUT_CONFIG_COMPILER_GCC_HPP
|
||||
|
|
|
@ -69,6 +69,12 @@
|
|||
# define SPROUT_USE_BUILTIN_CMATH_FUNCTION 0
|
||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_CMATH_FUNCTION
|
||||
|
||||
#ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION
|
||||
# define SPROUT_USE_BUILTIN_BIT_OPERATION 1
|
||||
#else // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION
|
||||
# define SPROUT_USE_BUILTIN_BIT_OPERATION 0
|
||||
#endif // #ifndef SPROUT_CONFIG_DISABLE_BUILTIN_BIT_OPERATION
|
||||
|
||||
#ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION
|
||||
# define SPROUT_USE_INDEX_ITERATOR_IMPLEMENTATION 1
|
||||
#else // #ifndef SPROUT_CONFIG_DISABLE_SUPPORT_TEMPORARY_CONTAINER_ITERATION
|
||||
|
|
Loading…
Reference in a new issue