forked from cheng/wallet
Fixed template bug in serialization
This commit is contained in:
parent
97c98cf1e5
commit
885c51bfc1
75
bit_hacks.h
75
bit_hacks.h
@ -1,75 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// We should template this to use __popcnt64 if available
|
|
||||||
// but that is premature optimization
|
|
||||||
inline uint64_t bitcount(uint64_t c) {
|
|
||||||
c = c - ((c >> 1) & 0x5555555555555555);
|
|
||||||
c = ((c >> 2) & 0x3333333333333333) +
|
|
||||||
(c & 0x3333333333333333);
|
|
||||||
c = ((c >> 4) + c) & 0x0F0F0F0F0F0F0F0F;
|
|
||||||
c = ((c >> 8) + c) & 0x00FF00FF00FF00FF;
|
|
||||||
c = ((c >> 16) + c) & 0x0000FFFF0000FFFF;
|
|
||||||
c = ((c >> 32) + c) & 0x00000000FFFFFFFF;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
// http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog "Bit Hacks"
|
|
||||||
// Find ⌊log2⌋
|
|
||||||
// We should template this to use lzcnt64, __builtin_clz or _BitScanReverse if available,
|
|
||||||
// but that is premature optimization.
|
|
||||||
inline auto rounded_log2(uint32_t v) {
|
|
||||||
// This algorithm extends to 64 bits, by adding a step, shrinks to sixteen bits by removing a step.
|
|
||||||
decltype(v) r{ 0 }, s;
|
|
||||||
// This redundant initialization and redundant |= of r can be eliminated,
|
|
||||||
// but eliminating it obfuscates the simplicity of the algorithm.
|
|
||||||
s = (v > 0xFFFF) << 4; v >>= s; r |= s;
|
|
||||||
s = (v > 0x00FF) << 3; v >>= s; r |= s;
|
|
||||||
s = (v > 0x000F) << 2; v >>= s; r |= s;
|
|
||||||
s = (v > 0x0003) << 1; v >>= s; r |= s;
|
|
||||||
r |= (v >> 1);
|
|
||||||
// result of ⌊log2(v)⌋ is in r
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
// For trailing bits, consider int __builtin_ctz (unsigned int x)
|
|
||||||
// http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightLinear
|
|
||||||
|
|
||||||
// Count the consecutive trailing zero bits
|
|
||||||
inline auto trailing_zero_bits(uint64_t v) {
|
|
||||||
unsigned int c;
|
|
||||||
if (v & 0x3F) {
|
|
||||||
v = (v ^ (v - 1)) >> 1; // Set v's trailing 0s to 1s and zero rest
|
|
||||||
for (c = 0; v; c++) {
|
|
||||||
v >>= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c = 1;
|
|
||||||
if ((v & 0xffffffff) == 0) {
|
|
||||||
v >>= 32;
|
|
||||||
c += 32;
|
|
||||||
}
|
|
||||||
if ((v & 0xffff) == 0) {
|
|
||||||
v >>= 16;
|
|
||||||
c += 16;
|
|
||||||
}
|
|
||||||
if ((v & 0xff) == 0){
|
|
||||||
v >>= 8;
|
|
||||||
c += 8;
|
|
||||||
}
|
|
||||||
if ((v & 0xf) == 0){
|
|
||||||
v >>= 4;
|
|
||||||
c += 4;
|
|
||||||
}
|
|
||||||
if ((v & 0x3) == 0) {
|
|
||||||
v >>= 2;
|
|
||||||
c += 2;
|
|
||||||
}
|
|
||||||
if ((v & 0x1) == 0) {
|
|
||||||
v >>= 1;
|
|
||||||
c += 1;
|
|
||||||
}
|
|
||||||
c -= v & 0x01;
|
|
||||||
}
|
|
||||||
return c;
|
|
||||||
}
|
|
@ -14,11 +14,11 @@ namespace ro {
|
|||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr bool is_standard_unsigned_integer =
|
constexpr bool is_standard_unsigned_integer =
|
||||||
_Is_any_of_v<std::remove_cv_t<T>, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>;
|
_Is_any_of_v<std::remove_cvref<T>::type, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr bool is_standard_signed_integer =
|
constexpr bool is_standard_signed_integer =
|
||||||
_Is_any_of_v<std::remove_cv_t<T>, signed char, signed short, signed int, signed long, signed long long>;
|
_Is_any_of_v<std::remove_cvref<T>::type, signed char, signed short, signed int, signed long, signed long long>;
|
||||||
|
|
||||||
// A compile time test to see if desired casts work, and make sure that
|
// A compile time test to see if desired casts work, and make sure that
|
||||||
// undesired casts do not work
|
// undesired casts do not work
|
||||||
|
@ -105,11 +105,11 @@ namespace ro {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This template generates a span over const unsigned bytes for
|
// This template generates a span over an indexable byte type,
|
||||||
// any range over bytes, such as a C array or an std::array
|
// such as a C array or an std::array, but not pointers
|
||||||
template < typename T>
|
template < typename T>
|
||||||
std::enable_if_t<
|
std::enable_if_t<
|
||||||
sizeof(std::size(std::declval<T>())) >= sizeof(int) &&
|
!std::is_pointer<T>::value &&
|
||||||
sizeof(std::declval<T>()[0]) == 1,
|
sizeof(std::declval<T>()[0]) == 1,
|
||||||
std::span<const byte>
|
std::span<const byte>
|
||||||
> serialize(const T& a) {
|
> serialize(const T& a) {
|
||||||
@ -453,8 +453,8 @@ namespace ristretto255 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template < typename T>
|
template < typename T>
|
||||||
decltype(ro::serialize(std::declval<T>()), hsh<hashsize>())&
|
decltype(ro::serialize(std::declval<std::remove_cvref<T>::type >()), hsh<hashsize>())&
|
||||||
operator <<(const T& j) {
|
operator <<(const T & j) {
|
||||||
return *this << ro::serialize(j);
|
return *this << ro::serialize(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -468,7 +468,7 @@ namespace ristretto255 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hsh<hashsize>& operator <<(const std::span<const byte>& j) {
|
hsh<hashsize>& operator <<(const std::span<const byte> j) {
|
||||||
int i = crypto_generichash_blake2b_update(
|
int i = crypto_generichash_blake2b_update(
|
||||||
&st,
|
&st,
|
||||||
&j[0],
|
&j[0],
|
||||||
|
Loading…
Reference in New Issue
Block a user