// -*- C++ -*-
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___BITS
#define _LIBCPP___BITS

#include <__config>

#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif

_LIBCPP_PUSH_MACROS
#include <__undef_macros>


_LIBCPP_BEGIN_NAMESPACE_STD

#ifndef _LIBCPP_COMPILER_MSVC

inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_ctz(unsigned __x)           _NOEXCEPT { return __builtin_ctz(__x); }

inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_ctz(unsigned long __x)      _NOEXCEPT { return __builtin_ctzl(__x); }

inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_ctz(unsigned long long __x) _NOEXCEPT { return __builtin_ctzll(__x); }


inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_clz(unsigned __x)           _NOEXCEPT { return __builtin_clz(__x); }

inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_clz(unsigned long __x)      _NOEXCEPT { return __builtin_clzl(__x); }

inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_clz(unsigned long long __x) _NOEXCEPT { return __builtin_clzll(__x); }


inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_popcount(unsigned __x)           _NOEXCEPT { return __builtin_popcount(__x); }

inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_popcount(unsigned long __x)      _NOEXCEPT { return __builtin_popcountl(__x); }

inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR
int __libcpp_popcount(unsigned long long __x) _NOEXCEPT { return __builtin_popcountll(__x); }

#else  // _LIBCPP_COMPILER_MSVC

// Precondition:  __x != 0
inline _LIBCPP_INLINE_VISIBILITY
int __libcpp_ctz(unsigned __x) {
  static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
  static_assert(sizeof(unsigned long) == 4, "");
  unsigned long __where;
  if (_BitScanForward(&__where, __x))
    return static_cast<int>(__where);
  return 32;
}

inline _LIBCPP_INLINE_VISIBILITY
int __libcpp_ctz(unsigned long __x) {
    static_assert(sizeof(unsigned long) == sizeof(unsigned), "");
    return __ctz(static_cast<unsigned>(__x));
}

inline _LIBCPP_INLINE_VISIBILITY
int __libcpp_ctz(unsigned long long __x) {
    unsigned long __where;
#if defined(_LIBCPP_HAS_BITSCAN64)
    (defined(_M_AMD64) || defined(__x86_64__))
  if (_BitScanForward64(&__where, __x))
    return static_cast<int>(__where);
#else
  // Win32 doesn't have _BitScanForward64 so emulate it with two 32 bit calls.
  if (_BitScanForward(&__where, static_cast<unsigned long>(__x)))
    return static_cast<int>(__where);
  if (_BitScanForward(&__where, static_cast<unsigned long>(__x >> 32)))
    return static_cast<int>(__where + 32);
#endif
  return 64;
}

// Precondition:  __x != 0
inline _LIBCPP_INLINE_VISIBILITY
int __libcpp_clz(unsigned __x) {
  static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
  static_assert(sizeof(unsigned long) == 4, "");
  unsigned long __where;
  if (_BitScanReverse(&__where, __x))
    return static_cast<int>(31 - __where);
  return 32; // Undefined Behavior.
}

inline _LIBCPP_INLINE_VISIBILITY
int __libcpp_clz(unsigned long __x) {
    static_assert(sizeof(unsigned) == sizeof(unsigned long), "");
    return __libcpp_clz(static_cast<unsigned>(__x));
}

inline _LIBCPP_INLINE_VISIBILITY
int __libcpp_clz(unsigned long long __x) {
  unsigned long __where;
#if defined(_LIBCPP_HAS_BITSCAN64)
  if (_BitScanReverse64(&__where, __x))
    return static_cast<int>(63 - __where);
#else
  // Win32 doesn't have _BitScanReverse64 so emulate it with two 32 bit calls.
  if (_BitScanReverse(&__where, static_cast<unsigned long>(__x >> 32)))
    return static_cast<int>(63 - (__where + 32));
  if (_BitScanReverse(&__where, static_cast<unsigned long>(__x)))
    return static_cast<int>(63 - __where);
#endif
  return 64; // Undefined Behavior.
}

inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned __x) {
  static_assert(sizeof(unsigned) == 4, "");
  return __popcnt(__x);
}

inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long __x) {
  static_assert(sizeof(unsigned long) == 4, "");
  return __popcnt(__x);
}

inline _LIBCPP_INLINE_VISIBILITY int __libcpp_popcount(unsigned long long __x) {
  static_assert(sizeof(unsigned long long) == 8, "");
  return __popcnt64(__x);
}

#endif // _LIBCPP_COMPILER_MSVC

_LIBCPP_END_NAMESPACE_STD

_LIBCPP_POP_MACROS

#endif  // _LIBCPP__BITS
