#ifndef BITS_H
#define BITS_H
#include "third_party/python/Modules/_decimal/libmpdec/mpdecimal.h"
/* clang-format off */

/*
 * Check if ð is a power of 2.
 */
static inline int
ispower2(mpd_size_t n)
{
    return n != 0 && (n & (n-1)) == 0;
}

/*
 * Returns most significant bit position of ð.
 * Assumptions: ð â  0
 */
static inline int
mpd_bsr(mpd_size_t n)
{
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
    return __builtin_clzll(n) ^ (sizeof(long long) * CHAR_BIT - 1);
#else
    int pos = 0;
    mpd_size_t tmp;
    tmp = n >> 32; if (tmp != 0) { n = tmp; pos += 32; }
    tmp = n >> 16; if (tmp != 0) { n = tmp; pos += 16; }
    tmp = n >>  8; if (tmp != 0) { n = tmp; pos +=  8; }
    tmp = n >>  4; if (tmp != 0) { n = tmp; pos +=  4; }
    tmp = n >>  2; if (tmp != 0) { n = tmp; pos +=  2; }
    tmp = n >>  1; if (tmp != 0) { n = tmp; pos +=  1; }
    return pos + (int)n - 1;
#endif
}

/*
 * Return the least significant bit position of n from 0 to 31 (63).
 * Assumptions: n != 0.
 */
static inline int
mpd_bsf(mpd_size_t n)
{
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
    return __builtin_ctzll(n);
#else
    int pos;
    pos = 63;
    if (n & 0x00000000FFFFFFFFULL) { pos -= 32; } else { n >>= 32; }
    if (n & 0x000000000000FFFFULL) { pos -= 16; } else { n >>= 16; }
    if (n & 0x00000000000000FFULL) { pos -=  8; } else { n >>=  8; }
    if (n & 0x000000000000000FULL) { pos -=  4; } else { n >>=  4; }
    if (n & 0x0000000000000003ULL) { pos -=  2; } else { n >>=  2; }
    if (n & 0x0000000000000001ULL) { pos -=  1; }
    return pos;
#endif
}

#endif /* BITS_H */
