1
0
forked from cheng/wallet

minor template cleanup and clarification

This commit is contained in:
Cheng 2022-02-28 15:54:21 +10:00
parent 885c51bfc1
commit 251325836a
No known key found for this signature in database
GPG Key ID: D51301E176B31828
7 changed files with 28 additions and 22 deletions

View File

@ -53,10 +53,10 @@ namespace ro {
return retval;
}
}
else if constexpr (std::is_same< T, std::span<const byte>>::value) {
else if constexpr (std::is_same_v<std::remove_cvref_t<T>, std::span<const byte>>) {
return (*this)->Isqlite3_column_blob(i);
}
else if constexpr (std::is_same< T, const char*>::value) {
else if constexpr (std::is_same_v<std::remove_cvref_t<T>, const char*>) {
auto sz{ (*this)->Isqlite3_column_text(i) };
// if (!IsValidUtf8String(sz)) throw NonUtf8DataInDatabase();
return sz;
@ -83,10 +83,10 @@ namespace ro {
j = (*this)->Isqlite3_column_int(i);
}
}
else if constexpr (std::is_same< T, std::span<const byte>>::value) {
else if constexpr (std::is_same_v<std::remove_cvref_t<T>, std::span<const byte>>) {
j = (*this)->Isqlite3_column_blob(i);
}
else if constexpr (std::is_same< T, const char*>::value) {
else if constexpr (std::is_same_v<std::remove_cvref_t<T>, const char*>) {
j = (*this)->Isqlite3_column_text(i);
}
else {

View File

@ -14,27 +14,30 @@ namespace ro {
template <class T>
constexpr bool is_standard_unsigned_integer =
_Is_any_of_v<std::remove_cvref<T>::type, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>;
_Is_any_of_v<std::remove_cvref_t<T>, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>;
template <class T>
constexpr bool is_standard_signed_integer =
_Is_any_of_v<std::remove_cvref<T>::type, signed char, signed short, signed int, signed long, signed long long>;
_Is_any_of_v<std::remove_cvref_t<T>, 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
// undesired casts do not work
template <class T, class U> struct has_constructor {
template <class T, class U> struct is_constructible_from {
template <typename V> static constexpr decltype(T(std::declval<V>()), bool()) test() {
return true;
}
template <typename V> static constexpr bool test(int = 0) {
return false;
}
static constexpr bool value = has_constructor::template test<U>();
static constexpr bool value = is_constructible_from::template test<U>();
};
template <class T, class U>
inline constexpr bool is_constructible_from_v = is_constructible_from<T, U>::value;
template <class T, class... _Types>
inline constexpr bool is_constructible_from_any_of = //true if T is constructible from any of the listed types
std::disjunction<has_constructor<T, _Types>...>::value;
std::disjunction<is_constructible_from<T, _Types>...>::value;
template <bool _First_value, class _First, class... _Rest>
struct _Junction { // handle false trait or last trait
@ -56,7 +59,11 @@ namespace ro {
template <class T, class... _Types>
inline constexpr bool is_constructible_from_all_of = //true if T is constructible from any of the listed types
junction<has_constructor<T, _Types>...>::value;
junction<is_constructible_from<T, _Types>...>::value;
template<class T, class U>
inline constexpr bool is_same = std::is_same_v<std::remove_cvref_t<T>, std::remove_cvref_t<U>>;
}
/*spaceship operator for any pair of types that take an index
@ -88,7 +95,7 @@ decltype(std::declval<T>()[0] <=> std::declval<U>()[0]) operator <=> (
if (std::is_eq(retval)) {
if (slh.size() > srh.size()) {
assert(prh == srh.end() && plh < slh.end());
if constexpr (std::is_arithmetic<std::remove_cvref<decltype(std::declval<T>()[0])>::type>::value) {
if constexpr (std::is_arithmetic<std::remove_cvref_t<decltype(std::declval<T>()[0])> >::value) {
while (
plh < slh.end()
&& std::is_eq(retval = plh[0] <=> 0)
@ -102,7 +109,7 @@ decltype(std::declval<T>()[0] <=> std::declval<U>()[0]) operator <=> (
}
if (slh.size() < srh.size()) {
assert(plh == slh.end() && prh < srh.end());
if constexpr (std::is_arithmetic<std::remove_cvref<decltype(std::declval<U>()[0])>::type>::value) {
if constexpr (std::is_arithmetic<std::remove_cvref_t<decltype(std::declval<U>()[0])> >::value) {
while (
prh < srh.end()
&& std::is_eq(retval = prh[0] <=> 0)

@ -1 +1 @@
Subproject commit d30251f03e646abd07b5399654f1f5dcea9a6b38
Subproject commit 32cba2b5e90c2b98b61e8cc4c8105c0a27725fb0

View File

@ -74,7 +74,7 @@ namespace ro {
void map_base_to_mpir58(const char*, char*, size_t);
template <typename T> class base58 : public CompileSizedString<
((sizeof(T) * 8 + 4) * 4943ui64 + 28955ui64) / 28956ui64 - (std::is_same_v<T, scalar> ? 1 : 0)> {
((sizeof(T) * 8 + 4) * 4943ui64 + 28955ui64) / 28956ui64 - (std::is_same_v<std::remove_cvref_t<T>, scalar> ? 1 : 0)> {
public:
// The rational number 4943 / 28956 is minisculy larger than log(2)/log(58)
// hence rounding up the nearest integer guarantees it will always be big enough.
@ -108,7 +108,7 @@ namespace ro {
if (thl == nullptr)thl = new thread_local__();
mpz_ui_pow_ui(thl->n, 58, base58<T>::length);
if constexpr (std::is_same_v<T, scalar>) {
if constexpr (std::is_same_v<std::remove_cvref_t<T>, scalar>) {
mpz_fdiv_q(thl->q, thl->n, mpir::ristretto25519_curve_order);
}
else {
@ -130,7 +130,7 @@ namespace ro {
map_base_to_mpir58(p, ps, strsc.length);
if (p[base58::length] > ' ')throw OversizeBase58String();
if (mpz_set_str(thl->n, ps, 58))throw BadStringRepresentationOfCryptoIdException();
if constexpr (std::is_same_v<T, scalar>) {
if constexpr (std::is_same_v<std::remove_cvref_t<T>, scalar>) {
mpz_fdiv_qr(thl->q, thl->r, thl->n, mpir::ristretto25519_curve_order);
}
else {
@ -153,7 +153,7 @@ namespace ro {
) {
mpir_ui ck{ (static_cast<uint64_t>(fasthash(sc)) * static_cast<uint64_t>(check_range_m<T>)) >> 32 };
mpz_import(thl->n, sizeof(sc.blob), -1, 1, -1, 0, &sc.blob[0]);
if constexpr (std::is_same_v<T, scalar>) {
if constexpr (std::is_same_v<std::remove_cvref_t<T>, scalar>) {
mpz_addmul_ui(thl->n, mpir::ristretto25519_curve_order, ck);
}
else {

View File

@ -750,14 +750,14 @@ namespace ristretto255 {
static_assert(ro::is_serializable<unsigned int>::value);
static_assert(ro::is_serializable<char*>::value);
static_assert(ro::is_serializable<uint8_t*>::value == false); //false because uint8_t * has no inband terminator
static_assert(false == ro::is_serializable<wxString>::value && !ro::has_constructor<hash<256>, wxString>::value, "wxStrings are apt to convert anything to anything, with surprising and unexpected results");
static_assert(false == ro::is_serializable<wxString>::value && !ro::is_constructible_from_v<hash<256>, wxString>, "wxStrings are apt to convert anything to anything, with surprising and unexpected results");
static_assert(ro::is_serializable<decltype(std::declval<wxString>().ToUTF8())>::value == true);
static_assert(ro::is_constructible_from_all_of<scalar, int, hash<512>, std::array<uint8_t, crypto_core_ristretto255_BYTES>>);
static_assert(ro::is_constructible_from_all_of<hash<256>, char*, short, unsigned short, hash<512>, point, scalar>, "want to be able to hash anything serializable");
static_assert(false == ro::is_constructible_from_any_of<int, scalar, point, hsh<512>, hash<256>>);
static_assert(false == ro::is_constructible_from_any_of <scalar, wxString, hash<256>, byte*>, "do not want indiscriminate casts");
static_assert(false == ro::is_constructible_from_any_of <point, wxString, hash<256>, byte*>, "do not want indiscriminate casts ");
static_assert(false == ro::has_constructor<hash<256>, float>::value);
static_assert(false == ro::is_constructible_from_v<hash<256>, float>);
static_assert(ro::is_serializable<float>::value == false);//Need to convert floats to
// their machine independent representation, possibly through idexp, frexp
// and DBL_MANT_DIG

View File

@ -5,7 +5,7 @@
#include <string>
//#include <initializer_list> // for initializer_list
//#include <type_traits>
#include <memory> // for shared_ptr, unique_ptr
//#include <memory> // for shared_ptr, unique_ptr
#include <span>
#include "ILog.h"
#include "localization.h"

View File

@ -1,5 +1,4 @@
#pragma once
// Converts a bit buffer, arbitrarily positioned with respect to byte boundaries, into a base sixty four numeral.
// In release mode, returns without doing anything if the output string buffer is too small.
// In debug mode, halts execution with an assert. Should throw, need to put in and unit test.
@ -25,7 +24,7 @@ uint8_t base64_to_bytes(uint8_t* byteBuffer, uint_fast32_t byteCount, const char
Returns a uint8_t containing the excess bits of the last numeral in its low order part.*/
template < typename T>
std::enable_if_t<
sizeof(std::size(std::declval<T>())) >= sizeof(int) &&
!std::is_pointer<T>::value &&
sizeof(std::declval<T>()[0]) == 1,
uint8_t
>base64_to_bytes( T& byteRange, const char* base64Numerals) {