14#ifndef NANOVDB_UTIL_UTIL_H_HAS_BEEN_INCLUDED
15#define NANOVDB_UTIL_UTIL_H_HAS_BEEN_INCLUDED
19typedef signed char int8_t;
22typedef long long int64_t;
23typedef unsigned char uint8_t;
24typedef unsigned int uint32_t;
25typedef unsigned short uint16_t;
26typedef unsigned long long uint64_t;
28#define NANOVDB_ASSERT(x)
31#define UINT64_C(x) (x ## ULL)
37#if __cplusplus >= 202002L
47#ifdef NANOVDB_USE_IOSTREAMS
53#define NANOVDB_ASSERT(x) assert(x)
55#define NANOVDB_ASSERT(x)
58#if defined(NANOVDB_USE_INTRINSICS) && defined(_MSC_VER)
60#pragma intrinsic(_BitScanReverse)
61#pragma intrinsic(_BitScanForward)
62#pragma intrinsic(_BitScanReverse64)
63#pragma intrinsic(_BitScanForward64)
68#if defined(__CUDACC__) || defined(__HIP__)
71#define __hostdev__ __host__ __device__
94#define NANOVDB_RESTRICT __restrict
96#define NANOVDB_RESTRICT __restrict__
101#if defined(_MSC_VER) && defined(__CUDACC__)
102#define NANOVDB_HOSTDEV_DISABLE_WARNING __pragma("hd_warning_disable")
103#elif defined(__GNUC__) && defined(__CUDACC__)
104#define NANOVDB_HOSTDEV_DISABLE_WARNING _Pragma("hd_warning_disable")
106#define NANOVDB_HOSTDEV_DISABLE_WARNING
125#define NANOVDB_PRAGMA(X) _Pragma(#X)
126#define NANOVDB_DEPRECATED_HEADER(MSG) NANOVDB_PRAGMA(GCC warning MSG)
127#elif defined(_MSC_VER)
128#define NANOVDB_STRINGIZE_(MSG) #MSG
129#define NANOVDB_STRINGIZE(MSG) NANOVDB_STRINGIZE_(MSG)
130#define NANOVDB_DEPRECATED_HEADER(MSG) \
131 __pragma(message(__FILE__ "(" NANOVDB_STRINGIZE(__LINE__) ") : Warning: " MSG))
135#define NANOVDB_OFFSETOF(CLASS, MEMBER) ((int)(size_t)((char*)&((CLASS*)0)->MEMBER - (char*)0))
181 for (
char *p = dst; (*p++ = *src) !=
'\0'; ++src);
201 for (; i < max && src[i] !=
'\0'; ++i) dst[i] = src[i];
202 for (; i < max; ++i) dst[i] =
'\0';
216 if (num == 0) dst[len++] =
'0';
217 for (
int abs = num < 0 && bas == 10 ? -num : num; abs; abs /= bas) {
218 const int rem = abs % bas;
219 dst[len++] = rem > 9 ? rem - 10 +
'a' : rem +
'0';
221 if (num < 0) dst[len++] =
'-';
222 for (
char *a = dst, *b = a + len - 1; a < b; ++a, --b) {
241 while (*p !=
'\0') ++p;
255 while (*p !=
'\0') ++p;
269 while(*lhs !=
'\0' && (*lhs == *rhs)){
273 return *(
const unsigned char*)lhs - *(
const unsigned char*)rhs;
282 return strcmp(lhs, rhs) == 0;
289template <
typename T,
typename... Types>
297template <
typename T,
typename... Types>
312 const size_t wordCount = byteCount >> 3;
313 if (wordCount << 3 == byteCount) {
314 for (
auto *d = (uint64_t*)dst, *e = d + wordCount; d != e; ++d) *d = 0ULL;
316 for (
auto *d = (
char*)dst, *e = d + byteCount; d != e; ++d) *d =
'\0';
325template<
typename T0,
typename T1,
typename ...T>
331template<
typename T0,
typename T1>
337template<
typename T0,
typename T1,
typename ...T>
352template <
bool,
typename T =
void>
358template<
bool Test,
typename T =
void>
363template<
bool,
typename T =
void>
369template<
bool Test,
typename T =
void>
402template<
bool,
class TrueT,
class FalseT>
408template<
class TrueT,
class FalseT>
411template<
bool Test,
class TrueT,
class FalseT>
472template<
typename T,
typename ReferenceT>
480template<
typename T,
typename ReferenceT>
483template<
typename T,
typename ReferenceT>
495template<
typename AnyType,
template<
typename...>
class TemplateType>
498template<
typename... Args,
template<
typename...>
class TemplateType>
513 return reinterpret_cast<const char*
>(p) -
reinterpret_cast<const char*
>(q);
523template<
typename DstT =
void>
527 return reinterpret_cast<DstT*
>(
reinterpret_cast<char*
>(p) + offset);
535template<
typename DstT =
void>
539 return reinterpret_cast<const DstT*
>(
reinterpret_cast<const char*
>(p) + offset);
551#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
553#elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
555 _BitScanForward(&index, v);
556 return static_cast<uint32_t
>(index);
557#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
558 return static_cast<uint32_t
>(__builtin_ctzl(v));
561 static const unsigned char DeBruijn[32] = {
562 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9};
564#if defined(_MSC_VER) && !defined(__NVCC__)
566#pragma warning(disable : 4146)
568 return DeBruijn[uint32_t((v & -v) * 0x077CB531U) >> 27];
569#if defined(_MSC_VER) && !defined(__NVCC__)
583#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
584 return __ffsll(
static_cast<unsigned long long int>(v)) - 1;
585#elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
587 _BitScanForward64(&index, v);
588 return static_cast<uint32_t
>(index);
589#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
590 return static_cast<uint32_t
>(__builtin_ctzll(v));
593 static const unsigned char DeBruijn[64] = {
594 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28,
595 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11,
596 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10,
597 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12,
600#if defined(_MSC_VER) && !defined(__NVCC__)
602#pragma warning(disable : 4146)
604 return DeBruijn[uint64_t((v & -v) * UINT64_C(0x022FDD63CC95386D)) >> 58];
605#if defined(_MSC_VER) && !defined(__NVCC__)
621#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
622 return sizeof(uint32_t) * 8 - 1 - __clz(v);
623#elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
625 _BitScanReverse(&index, v);
626 return static_cast<uint32_t
>(index);
627#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
628 return sizeof(
unsigned long) * 8 - 1 - __builtin_clzl(v);
631 static const unsigned char DeBruijn[32] = {
632 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
633 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31};
639 return DeBruijn[uint32_t(v * 0x07C4ACDDU) >> 27];
650#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
651 return sizeof(
unsigned long) * 8 - 1 - __clzll(
static_cast<unsigned long long int>(v));
652#elif defined(_MSC_VER) && defined(NANOVDB_USE_INTRINSICS)
654 _BitScanReverse64(&index, v);
655 return static_cast<uint32_t
>(index);
656#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
657 return sizeof(
unsigned long) * 8 - 1 - __builtin_clzll(v);
659 const uint32_t* p =
reinterpret_cast<const uint32_t*
>(&v);
670#if (defined(__CUDA_ARCH__) || defined(__HIP__)) && defined(NANOVDB_USE_INTRINSICS)
674#elif defined(_MSC_VER) && defined(_M_X64) && (_MSC_VER >= 1928) && defined(NANOVDB_USE_INTRINSICS)
676 return uint32_t(__popcnt64(v));
677#elif (defined(__GNUC__) || defined(__clang__)) && defined(NANOVDB_USE_INTRINSICS)
679 return __builtin_popcountll(v);
682 v = v - ((v >> 1) & uint64_t(0x5555555555555555));
683 v = (v & uint64_t(0x3333333333333333)) + ((v >> 2) & uint64_t(0x3333333333333333));
684 return (((v + (v >> 4)) & uint64_t(0xF0F0F0F0F0F0F0F)) * uint64_t(0x101010101010101)) >> 56;
695#if defined(__CUDA_ARCH__) || defined(__HIP__)
696 return static_cast<uint64_t
>(
::atomicOr(
reinterpret_cast<unsigned long long int*
>(target),
697 static_cast<unsigned long long int>(mask)));
698#elif __cplusplus >= 202002L
699 return std::atomic_ref<uint64_t>(*target).fetch_or(mask, std::memory_order_relaxed);
700#elif defined(__GNUC__) || defined(__clang__)
701 return __atomic_fetch_or(target, mask, __ATOMIC_RELAXED);
702#elif defined(_MSC_VER)
703 static_assert(
sizeof(
long long) ==
sizeof(uint64_t),
"Unexpected long long size");
704 return static_cast<uint64_t
>(_InterlockedOr64(
705 reinterpret_cast<volatile long long*
>(target),
706 static_cast<long long>(mask)));
708#error "util::atomicOr: no implementation for this compiler"
719#if defined(__CUDA_ARCH__) || defined(__HIP__)
720 return static_cast<uint64_t
>(
::atomicAnd(
reinterpret_cast<unsigned long long int*
>(target),
721 static_cast<unsigned long long int>(mask)));
722#elif __cplusplus >= 202002L
723 return std::atomic_ref<uint64_t>(*target).fetch_and(mask, std::memory_order_relaxed);
724#elif defined(__GNUC__) || defined(__clang__)
725 return __atomic_fetch_and(target, mask, __ATOMIC_RELAXED);
726#elif defined(_MSC_VER)
727 static_assert(
sizeof(
long long) ==
sizeof(uint64_t),
"Unexpected long long size");
728 return static_cast<uint64_t
>(_InterlockedAnd64(
729 reinterpret_cast<volatile long long*
>(target),
730 static_cast<long long>(mask)));
732#error "util::atomicAnd: no implementation for this compiler"
738[[deprecated(
"Use nanovdb::util::findLowestOn instead")]]
740[[deprecated(
"Use nanovdb::util::findLowestOn instead")]]
742[[deprecated(
"Use nanovdb::util::findHighestOn instead")]]
744[[deprecated(
"Use nanovdb::util::findHighestOn instead")]]
746[[deprecated(
"Use nanovdb::util::countOn instead")]]
char * sprint(char *dst)
Definition Util.h:287
static constexpr bool is_const_v
Definition Util.h:381
uint32_t countOn(uint64_t v)
Definition Util.h:668
uint32_t findHighestOn(uint32_t v)
Returns the index of the highest, i.e. most significant, on bit in the specified 32 bit word.
Definition Util.h:618
char * strncpy(char *dst, const char *src, size_t max)
Copies the first num characters of src to dst. If the end of the source C string (which is signaled b...
Definition Util.h:197
int strcmp(const char *lhs, const char *rhs)
Compares two null-terminated byte strings lexicographically.
Definition Util.h:267
bool streq(const char *lhs, const char *rhs)
Test if two null-terminated byte strings are the same.
Definition Util.h:280
static DstT * PtrAdd(void *p, int64_t offset)
Adds a byte offset to a non-const pointer to produce another non-const pointer.
Definition Util.h:524
static constexpr bool is_pointer_v
Definition Util.h:397
static void * memzero(void *dst, size_t byteCount)
Zero initialization of memory.
Definition Util.h:309
char * strcpy(char *dst, const char *src)
Copy characters from src to dst.
Definition Util.h:178
typename remove_const< T >::type remove_const_t
Definition Util.h:429
bool empty(const char *str)
tests if a c-string str is empty, that is its first value is '\0'
Definition Util.h:156
typename remove_pointer< T >::type remove_pointer_t
Definition Util.h:463
uint32_t findLowestOn(uint32_t v)
Returns the index of the lowest, i.e. least significant, on bit in the specified 32 bit word.
Definition Util.h:548
static constexpr bool is_floating_point_v
Definition Util.h:347
char * strcat(char *dst, const char *src)
Appends a copy of the character string pointed to by src to the end of the character string pointed t...
Definition Util.h:237
static int64_t PtrDiff(const void *p, const void *q)
Compute the distance, in bytes, between two pointers, dist = p - q.
Definition Util.h:510
typename conditional< Test, TrueT, FalseT >::type conditional_t
Definition Util.h:412
uint64_t atomicOr(uint64_t *target, uint64_t mask)
Atomically ORs mask into the 64-bit word at target (relaxed ordering). Returns the old value....
Definition Util.h:693
char * sprint(char *dst, T var1, Types... var2)
prints a variable number of string and/or numbers to a destination string
Definition Util.h:298
uint64_t atomicAnd(uint64_t *target, uint64_t mask)
Atomically ANDs mask into the 64-bit word at target (relaxed ordering). Returns the old value....
Definition Util.h:717
typename match_const< T, ReferenceT >::type match_const_t
Definition Util.h:484
typename remove_const< T >::type remove_reference_t
Definition Util.h:446
T && declval() noexcept
Minimal implementation of std::declval, which converts any type T to.
typename disable_if< Test, T >::type disable_if_t
Definition Util.h:370
static constexpr bool is_same_v
Definition Util.h:338
typename enable_if< Test, T >::type enable_if_t
Definition Util.h:359
Definition GridHandle.h:27
uint32_t CountOn(uint64_t v)
Definition Util.h:747
__hostdev__ constexpr uint32_t strlen()
return the number of characters (including null termination) required to convert enum type to a strin...
Definition NanoVDB.h:209
uint32_t FindHighestOn(uint32_t v)
Definition Util.h:743
uint32_t FindLowestOn(uint32_t v)
Definition Util.h:739
#define NANOVDB_HOSTDEV_DISABLE_WARNING
Definition Util.h:106
#define __hostdev__
Definition Util.h:76
#define NANOVDB_ASSERT(x)
Definition Util.h:53
FalseT type
Definition Util.h:409
C++11 implementation of std::conditional.
Definition Util.h:403
TrueT type
Definition Util.h:403
T type
Definition Util.h:364
T type
Definition Util.h:356
C++11 implementation of std::enable_if.
Definition Util.h:353
static constexpr bool value
Definition Util.h:378
static constexpr bool value
Definition Util.h:375
C++11 implementation of std::is_floating_point.
Definition Util.h:344
static constexpr bool value
Definition Util.h:344
static constexpr bool value
Definition Util.h:394
Trait used to identify template parameter that are pointers.
Definition Util.h:388
static constexpr bool value
Definition Util.h:388
static constexpr bool value
Definition Util.h:332
static constexpr bool value
Definition Util.h:335
C++11 implementation of std::is_same.
Definition Util.h:327
static constexpr bool value
Definition Util.h:328
static const bool value
Definition Util.h:501
Metafunction used to determine if the first template parameter is a specialization of the class templ...
Definition Util.h:496
static const bool value
Definition Util.h:496
const typename remove_const< T >::type type
Definition Util.h:481
Trait used to transfer the const-ness of a reference type to another type.
Definition Util.h:473
typename remove_const< T >::type type
Definition Util.h:473
T type
Definition Util.h:426
Trait use to const from type. Default implementation is just a pass-through.
Definition Util.h:420
T type
Definition Util.h:420
T type
Definition Util.h:460
Trait use to remove pointer, i.e. "*", qualifier from a type. Default implementation is just a pass-t...
Definition Util.h:454
T type
Definition Util.h:454
T type
Definition Util.h:443
Trait use to remove reference, i.e. "&", qualifier from a type. Default implementation is just a pass...
Definition Util.h:437
T type
Definition Util.h:437