mirror of
https://github.com/neovim/neovim.git
synced 2026-03-10 10:03:46 +10:00
Experimental and subject to future changes. Add a way to redraw certain elements that are not redrawn while Nvim is waiting for input, or currently have no API to do so. This API covers all that can be done with the :redraw* commands, in addition to the following new features: - Immediately move the cursor to a (non-current) window. - Target a specific window or buffer to mark for redraw. - Mark a buffer range for redraw (replaces nvim__buf_redraw_range()). - Redraw the 'statuscolumn'.
107 lines
2.0 KiB
C
107 lines
2.0 KiB
C
// uncrustify:off
|
|
#include <math.h>
|
|
// uncrustify:on
|
|
#include <limits.h>
|
|
#include <stdint.h>
|
|
#include <string.h>
|
|
|
|
#ifdef HAVE_BITSCANFORWARD64
|
|
# include <intrin.h> // Required for _BitScanForward64
|
|
#endif
|
|
|
|
#include "nvim/math.h"
|
|
#include "nvim/vim_defs.h"
|
|
|
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
|
# include "math.c.generated.h"
|
|
#endif
|
|
|
|
int xfpclassify(double d)
|
|
FUNC_ATTR_CONST
|
|
{
|
|
uint64_t m;
|
|
|
|
memcpy(&m, &d, sizeof(m));
|
|
int e = 0x7ff & (m >> 52);
|
|
m = 0xfffffffffffffULL & m;
|
|
|
|
switch (e) {
|
|
default:
|
|
return FP_NORMAL;
|
|
case 0x000:
|
|
return m ? FP_SUBNORMAL : FP_ZERO;
|
|
case 0x7ff:
|
|
return m ? FP_NAN : FP_INFINITE;
|
|
}
|
|
}
|
|
|
|
int xisinf(double d)
|
|
FUNC_ATTR_CONST
|
|
{
|
|
return FP_INFINITE == xfpclassify(d);
|
|
}
|
|
|
|
int xisnan(double d)
|
|
FUNC_ATTR_CONST
|
|
{
|
|
return FP_NAN == xfpclassify(d);
|
|
}
|
|
|
|
/// Count trailing zeroes at the end of bit field.
|
|
int xctz(uint64_t x)
|
|
{
|
|
// If x == 0, that means all bits are zeroes.
|
|
if (x == 0) {
|
|
return 8 * sizeof(x);
|
|
}
|
|
|
|
// Use compiler builtin if possible.
|
|
#if defined(__clang__) || (defined(__GNUC__) && (__GNUC__ >= 4))
|
|
return __builtin_ctzll(x);
|
|
#elif defined(HAVE_BITSCANFORWARD64)
|
|
unsigned long index;
|
|
_BitScanForward64(&index, x);
|
|
return (int)index;
|
|
#else
|
|
int count = 0;
|
|
// Set x's trailing zeroes to ones and zero the rest.
|
|
x = (x ^ (x - 1)) >> 1;
|
|
|
|
// Increment count until there are just zero bits remaining.
|
|
while (x) {
|
|
count++;
|
|
x >>= 1;
|
|
}
|
|
|
|
return count;
|
|
#endif
|
|
}
|
|
|
|
/// Count number of set bits in bit field.
|
|
int popcount(uint64_t x)
|
|
{
|
|
// Use compiler builtin if possible.
|
|
#if defined(__clang__) || defined(__GNUC__)
|
|
return __builtin_popcountll(x);
|
|
#else
|
|
int count = 0;
|
|
for (; x != 0; x >>= 1) {
|
|
if (x & 1) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
#endif
|
|
}
|
|
|
|
/// For overflow detection, add a digit safely to an int value.
|
|
int vim_append_digit_int(int *value, int digit)
|
|
{
|
|
int x = *value;
|
|
if (x > ((INT_MAX - digit) / 10)) {
|
|
return FAIL;
|
|
}
|
|
*value = x * 10 + digit;
|
|
return OK;
|
|
}
|