struct
{ /* Note. This is dangerous in that if it's passed an rvalue, it returns rvalue-reference. */ template <typename T> constexpr auto operator () (T&& v) const HB_AUTO_RETURN ( std::forward<T> (v) )
}
HB_FUNCOBJ (hb_identity); struct
{ /* Like identity(), but only retains lvalue-references. Rvalues are returned as rvalues. */ template <typename T> constexpr T& operator () (T& v) const { return v; }
#ifndef HB_OPTIMIZE_SIZE if (((uintptr_t) pos & 7) == 0)
{ while (pos != end)
{ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wcast-align"
v = * (const uint64_t *) (pos++); #pragma GCC diagnostic pop
h ^= mix(v);
h *= m;
}
} else #endif
{ while (pos != end)
{
v = pos++->v;
h ^= mix(v);
h *= m;
}
}
pos2 = (constunsignedchar*)pos;
v = 0;
switch (len & 7) { case7: v ^= (uint64_t)pos2[6] << 48; HB_FALLTHROUGH; case6: v ^= (uint64_t)pos2[5] << 40; HB_FALLTHROUGH; case5: v ^= (uint64_t)pos2[4] << 32; HB_FALLTHROUGH; case4: v ^= (uint64_t)pos2[3] << 24; HB_FALLTHROUGH; case3: v ^= (uint64_t)pos2[2] << 16; HB_FALLTHROUGH; case2: v ^= (uint64_t)pos2[1] << 8; HB_FALLTHROUGH; case1: v ^= (uint64_t)pos2[0];
h ^= mix(v);
h *= m;
}
return mix(h);
}
staticinline uint32_t fasthash32(constvoid *buf, size_t len, uint32_t seed)
{ // the following trick converts the 64-bit hashcode to Fermat // residue, which shall retain information from both the higher // and lower parts of hashcode.
uint64_t h = fasthash64(buf, len, seed); return h - (h >> 32);
}
template <typename U1 = T1, typename U2 = T2,
hb_enable_if (std::is_default_constructible<U1>::value &&
std::is_default_constructible<U2>::value)>
hb_pair_t () : first (), second () {}
hb_pair_t (T1 a, T2 b) : first (std::forward<T1> (a)), second (std::forward<T2> (b)) {}
/* Note. In min/max impl, we can use hb_type_identity<T> for second argument. *However,thatwouldsilentlyconvertbetweendifferent-signednessintegers. *Insteadweaccepttwodifferenttypes,suchthatcompilercanerrif
* comparing integers of different signedness. */ struct
{ template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(a <= b ? a : b)
}
HB_FUNCOBJ (hb_min); struct
{ template <typename T, typename T2> constexpr auto operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(a >= b ? a : b)
}
HB_FUNCOBJ (hb_max); struct
{ template <typename T, typename T2, typename T3> constexpr auto operator () (T&& x, T2&& min, T3&& max) const HB_AUTO_RETURN
(hb_min (hb_max (std::forward<T> (x), std::forward<T2> (min)), std::forward<T3> (max)))
}
HB_FUNCOBJ (hb_clamp);
/* *Bithacks.
*/
/* Return the number of 1 bits in v. */ template <typename T> staticinlineunsignedint
hb_popcount (T v)
{ #if hb_has_builtin(__builtin_popcount) if (sizeof (T) <= sizeof (unsignedint)) return __builtin_popcount (v); #endif
assert (0); return0; /* Shut up stupid compiler. */
}
/* Returns the number of bits needed to store number */ template <typename T> staticinlineunsignedint
hb_bit_storage (T v)
{ if (unlikely (!v)) return0;
if (sizeof (T) <= 4)
{ /* "bithacks" */ constunsignedint b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000}; constunsignedint S[] = {1, 2, 4, 8, 16}; unsignedint r = 0; for (int i = 4; i >= 0; i--) if (v & b[i])
{
v >>= S[i];
r |= S[i];
} return r + 1;
} if (sizeof (T) <= 8)
{ /* "bithacks" */ const uint64_t b[] = {0x2ULL, 0xCULL, 0xF0ULL, 0xFF00ULL, 0xFFFF0000ULL, 0xFFFFFFFF00000000ULL}; constunsignedint S[] = {1, 2, 4, 8, 16, 32}; unsignedint r = 0; for (int i = 5; i >= 0; i--) if (v & b[i])
{
v >>= S[i];
r |= S[i];
} return r + 1;
} if (sizeof (T) == 16)
{ unsignedint shift = 64; return (v >> shift) ? hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift :
hb_bit_storage<uint64_t> ((uint64_t) v);
}
assert (0); return0; /* Shut up stupid compiler. */
}
/* Returns the number of zero bits in the least significant side of v */ template <typename T> staticinlineunsignedint
hb_ctz (T v)
{ if (unlikely (!v)) return8 * sizeof (T);
if (sizeof (T) <= 4)
{ /* "bithacks" */ unsignedint c = 32;
v &= - (int32_t) v; if (v) c--; if (v & 0x0000FFFF) c -= 16; if (v & 0x00FF00FF) c -= 8; if (v & 0x0F0F0F0F) c -= 4; if (v & 0x33333333) c -= 2; if (v & 0x55555555) c -= 1; return c;
} if (sizeof (T) <= 8)
{ /* "bithacks" */ unsignedint c = 64;
v &= - (int64_t) (v); if (v) c--; if (v & 0x00000000FFFFFFFFULL) c -= 32; if (v & 0x0000FFFF0000FFFFULL) c -= 16; if (v & 0x00FF00FF00FF00FFULL) c -= 8; if (v & 0x0F0F0F0F0F0F0F0FULL) c -= 4; if (v & 0x3333333333333333ULL) c -= 2; if (v & 0x5555555555555555ULL) c -= 1; return c;
} if (sizeof (T) == 16)
{ unsignedint shift = 64; return (uint64_t) v ? hb_bit_storage<uint64_t> ((uint64_t) v) :
hb_bit_storage<uint64_t> ((uint64_t) (v >> shift)) + shift;
}
assert (0); return0; /* Shut up stupid compiler. */
}
/* *Tinystuff.
*/
/* ASCII tag/character handling */ staticinlinebool ISALPHA (unsignedchar c)
{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } staticinlinebool ISALNUM (unsignedchar c)
{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } staticinlinebool ISSPACE (unsignedchar c)
{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; } staticinlineunsignedchar TOUPPER (unsignedchar c)
{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } staticinlineunsignedchar TOLOWER (unsignedchar c)
{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; } staticinlinebool ISHEX (unsignedchar c)
{ return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } staticinlineunsignedchar TOHEX (uint8_t c)
{ return (c & 0xF) <= 9 ? (c & 0xF) + '0' : (c & 0xF) + 'a' - 10; } staticinline uint8_t FROMHEX (unsignedchar c)
{ return (c >= '0' && c <= '9') ? c - '0' : TOLOWER (c) - 'a' + 10; }
staticinlineunsignedint DIV_CEIL (constunsignedint a, unsignedint b)
{ return (a + (b - 1)) / b; }
#undef ARRAY_LENGTH template <typename Type, unsignedint n> staticinlineunsignedint ARRAY_LENGTH (const Type (&)[n]) { return n; } /* A const version, but does not detect erratically being called on pointers. */ #define ARRAY_LENGTH_CONST(__array) ((signedint) (sizeof (__array) / sizeof (__array[0])))
staticinlinevoid *
hb_memcpy (void *__restrict dst, constvoid *__restrict src, size_t len)
{ /* It's illegal to pass 0 as size to memcpy. */ if (unlikely (!len)) return dst; return memcpy (dst, src, len);
}
staticinlineint
hb_memcmp (constvoid *a, constvoid *b, unsignedint len)
{ /* It's illegal to pass NULL to memcmp(), even if len is zero. *So,wrapit.
* https://sourceware.org/bugzilla/show_bug.cgi?id=23878 */ if (unlikely (!len)) return0; return memcmp (a, b, len);
}
staticinlinevoid *
hb_memset (void *s, int c, unsignedint n)
{ /* It's illegal to pass NULL to memset(), even if n is zero. */ if (unlikely (!n)) return s; return memset (s, c, n);
}
template <typename T> staticinlinebool
hb_in_range (T u, T lo, T hi)
{
static_assert (!std::is_signed<T>::value, "");
/* The casts below are important as if T is smaller than int,
* the subtract results will become a signed int! */ return (T)(u - lo) <= (T)(hi - lo);
} template <typename T> staticinlinebool
hb_in_ranges (T u, T lo1, T hi1)
{ return hb_in_range (u, lo1, hi1);
} template <typename T, typename ...Ts> staticinlinebool
hb_in_ranges (T u, T lo1, T hi1, Ts... ds)
{ return hb_in_range<T> (u, lo1, hi1) || hb_in_ranges<T> (u, ds...);
}
/* swap a and b */ /* a and b must not be equal! */ staticinlinevoid sort_r_swap(char *__restrict a, char *__restrict b,
size_t w)
{ char tmp, *end = a+w; for(; a < end; a++, b++) { SORT_R_SWAP(*a, *b, tmp); }
}
/* swap a, b iff a>b */ /* a and b must not be equal! */ /* __restrict is same as restrict but better support on old machines */ template <typename ...Ts> staticinlineint sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w, int (*compar)(constvoid *_a, constvoid *_b,
Ts... _ds),
Ts... ds)
{ if(compar(a, b, ds...) > 0) {
sort_r_swap(a, b, w); return1;
} return0;
}
/* Strategy: Loopintothelistfromtheleftandrightatthesametimetofind: -anitemontheleftthatisgreaterthanthepivot -anitemontherightthatislessthanthepivot Oncefound,theyareswappedandtheloopcontinues. Meanwhileitemsthatareequaltothepivotaremovedtotheedgesofthe array.
*/ while(pl < pr) { /* Move left hand items which are equal to the pivot to the far left.
break when we find an item that is greater than the pivot */ for(; pl < pr; pl += w) {
cmp = compar(pl, pivot, ds...); if(cmp > 0) { break; } elseif(cmp == 0) { if(ple < pl) { sort_r_swap(ple, pl, w); }
ple += w;
}
} /* break if last batch of left hand items were equal to pivot */ if(pl >= pr) { break; } /* Move right hand items which are equal to the pivot to the far right.
break when we find an item that is less than the pivot */ for(; pl < pr; ) {
pr -= w; /* Move right pointer onto an unprocessed item */
cmp = compar(pr, pivot, ds...); if(cmp == 0) {
pre -= w; if(pr < pre) { sort_r_swap(pr, pre, w); }
} elseif(cmp < 0) { if(pl < pr) { sort_r_swap(pl, pr, w); }
pl += w; break;
}
}
}
for (unsignedint i = 1; i < len; i++)
{ unsignedint j = i; while (j && compar (&array[j - 1], &array[i]) > 0)
j--; if (i == j) continue; /* Move item i to occupy place for item j, shift what's in between. */
{
T t = array[i];
memmove (&array[j + 1], &array[j], (i - j) * sizeof (T));
array[j] = t;
} if (array2)
{
T3 t = array2[i];
memmove (&array2[j + 1], &array2[j], (i - j) * sizeof (T3));
array2[j] = t;
}
}
}
struct
{ HB_PARTIALIZE(2); template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
}
HB_FUNCOBJ (hb_bitwise_and); struct
{ HB_PARTIALIZE(2); template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
}
HB_FUNCOBJ (hb_bitwise_or); struct
{ HB_PARTIALIZE(2); template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
}
HB_FUNCOBJ (hb_bitwise_xor); struct
{ HB_PARTIALIZE(2); template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a & b)
}
HB_FUNCOBJ (hb_bitwise_lt); struct
{ HB_PARTIALIZE(2); template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
}
HB_FUNCOBJ (hb_bitwise_gt); // aka sub struct
{ HB_PARTIALIZE(2); template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (~a | b)
}
HB_FUNCOBJ (hb_bitwise_le); struct
{ HB_PARTIALIZE(2); template <typename T> constexpr auto operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | ~b)
}
HB_FUNCOBJ (hb_bitwise_ge); struct
{ template <typename T> constexpr auto operator () (const T &a) const HB_AUTO_RETURN (~a)
}
HB_FUNCOBJ (hb_bitwise_neg);
struct
{ HB_PARTIALIZE(2); template <typename T, typename T2> constexpr auto operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a + b)
}
HB_FUNCOBJ (hb_add); struct
{ HB_PARTIALIZE(2); template <typename T, typename T2> constexpr auto operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a - b)
}
HB_FUNCOBJ (hb_sub); struct
{ HB_PARTIALIZE(2); template <typename T, typename T2> constexpr auto operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (b - a)
}
HB_FUNCOBJ (hb_rsub); struct
{ HB_PARTIALIZE(2); template <typename T, typename T2> constexpr auto operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b)
}
HB_FUNCOBJ (hb_mul); struct
{ HB_PARTIALIZE(2); template <typename T, typename T2> constexpr auto operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a / b)
}
HB_FUNCOBJ (hb_div); struct
{ HB_PARTIALIZE(2); template <typename T, typename T2> constexpr auto operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a % b)
}
HB_FUNCOBJ (hb_mod); struct
{ template <typename T> constexpr auto operator () (const T &a) const HB_AUTO_RETURN (+a)
}
HB_FUNCOBJ (hb_pos); struct
{ template <typename T> constexpr auto operator () (const T &a) const HB_AUTO_RETURN (-a)
}
HB_FUNCOBJ (hb_neg); struct
{ template <typename T> constexpr auto operator () (T &a) const HB_AUTO_RETURN (++a)
}
HB_FUNCOBJ (hb_inc); struct
{ template <typename T> constexpr auto operator () (T &a) const HB_AUTO_RETURN (--a)
}
HB_FUNCOBJ (hb_dec);
/* Adapted from kurbo implementation with extra parameters added, *andfindingforaparticularrangeinsteadof0. * *Fordocumentationandimplementationsee: * *[ITPmethod]:https://en.wikipedia.org/wiki/ITP_Method *[AnEnhancementoftheBisectionMethodAveragePerformancePreservingMinmaxOptimality]:https://dl.acm.org/doi/10.1145/3423597 *https://docs.rs/kurbo/0.8.1/kurbo/common/fn.solve_itp.html *https://github.com/linebender/kurbo/blob/fd839c25ea0c98576c7ce5789305822675a89938/src/common.rs#L162-L248
*/ template <typename func_t> double solve_itp (func_t f, double a, double b, double epsilon, double min_y, double max_y, double &ya, double &yb, double &y)
{ unsigned n1_2 = (unsigned) (hb_max (ceil (log2 ((b - a) / epsilon)) - 1.0, 0.0)); constunsigned n0 = 1; // Hardwired constdouble k1 = 0.2 / (b - a); // Hardwired. unsigned nmax = n0 + n1_2; double scaled_epsilon = epsilon * double (1llu << nmax); double _2_epsilon = 2.0 * epsilon; while (b - a > _2_epsilon)
{ double x1_2 = 0.5 * (a + b); double r = scaled_epsilon - 0.5 * (b - a); double xf = (yb * a - ya * b) / (yb - ya); double sigma = x1_2 - xf; double b_a = b - a; // This has k2 = 2 hardwired for efficiency. double b_a_k2 = b_a * b_a; double delta = k1 * b_a_k2; int sigma_sign = sigma >= 0 ? +1 : -1; double xt = delta <= fabs (x1_2 - xf) ? xf + delta * sigma_sign : x1_2; double xitp = fabs (xt - x1_2) <= r ? xt : x1_2 - r * sigma_sign; double yitp = f (xitp); if (yitp > max_y)
{
b = xitp;
yb = yitp;
} elseif (yitp < min_y)
{
a = xitp;
ya = yitp;
} else
{
y = yitp; return xitp;
}
scaled_epsilon *= 0.5;
} return0.5 * (a + b);
}
#endif/* HB_ALGS_HH */
Messung V0.5 in Prozent
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.31Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.