src/util: change TriBool logic to use a bool template parameter
This commit is contained in:
+21
-20
@@ -155,7 +155,7 @@ TEST_CASE("noncopyable") {
|
|||||||
namespace {
|
namespace {
|
||||||
template <class T>
|
template <class T>
|
||||||
struct TestTriBool {
|
struct TestTriBool {
|
||||||
static void test(bool expect_true, int x) noexcept {
|
static void test(bool expect_true) noexcept {
|
||||||
static_assert(std::is_class<T>::value);
|
static_assert(std::is_class<T>::value);
|
||||||
static_assert(std::is_nothrow_default_constructible<T>::value);
|
static_assert(std::is_nothrow_default_constructible<T>::value);
|
||||||
static_assert(std::is_nothrow_destructible<T>::value);
|
static_assert(std::is_nothrow_destructible<T>::value);
|
||||||
@@ -171,7 +171,6 @@ struct TestTriBool {
|
|||||||
#endif
|
#endif
|
||||||
static_assert(!bool(T(false)));
|
static_assert(!bool(T(false)));
|
||||||
static_assert(bool(T(true)));
|
static_assert(bool(T(true)));
|
||||||
static_assert(bool(T(T::Third)) == (T::Third > T::False));
|
|
||||||
static_assert(T(false) == T::False);
|
static_assert(T(false) == T::False);
|
||||||
static_assert(T(true) == T::True);
|
static_assert(T(true) == T::True);
|
||||||
static_assert(T(T::False) == T::False);
|
static_assert(T(T::False) == T::False);
|
||||||
@@ -232,7 +231,7 @@ struct TestTriBool {
|
|||||||
CHECK(!a.isStrictTrue());
|
CHECK(!a.isStrictTrue());
|
||||||
CHECK(!a.isStrictBool());
|
CHECK(!a.isStrictBool());
|
||||||
CHECK(a.isThird());
|
CHECK(a.isThird());
|
||||||
a = x;
|
a = 99;
|
||||||
CHECK(a.getValue() == T::Third);
|
CHECK(a.getValue() == T::Third);
|
||||||
if (expect_true) {
|
if (expect_true) {
|
||||||
CHECK(a);
|
CHECK(a);
|
||||||
@@ -255,26 +254,28 @@ struct TestTriBool {
|
|||||||
|
|
||||||
TEST_CASE("TriBool") {
|
TEST_CASE("TriBool") {
|
||||||
using upx::TriBool, upx::tribool;
|
using upx::TriBool, upx::tribool;
|
||||||
//
|
|
||||||
static_assert(!tribool(false));
|
static_assert(!tribool(false));
|
||||||
static_assert(tribool(true));
|
static_assert(tribool(true));
|
||||||
static_assert(!tribool(tribool::Third));
|
static_assert(!tribool(tribool::Third));
|
||||||
TestTriBool<tribool>::test(false, -1);
|
TestTriBool<tribool>::test(false);
|
||||||
//
|
#if DEBUG || 1
|
||||||
TestTriBool<TriBool<upx_int8_t> >::test(false, -99990);
|
TestTriBool<TriBool<upx_int8_t> >::test(false);
|
||||||
TestTriBool<TriBool<upx_int16_t> >::test(false, -99991);
|
TestTriBool<TriBool<upx_uint8_t> >::test(false);
|
||||||
TestTriBool<TriBool<upx_int32_t> >::test(false, -99992);
|
TestTriBool<TriBool<upx_int16_t> >::test(false);
|
||||||
TestTriBool<TriBool<upx_int64_t> >::test(false, -99993);
|
TestTriBool<TriBool<upx_uint16_t> >::test(false);
|
||||||
//
|
TestTriBool<TriBool<upx_int32_t> >::test(false);
|
||||||
TestTriBool<TriBool<unsigned, 2> >::test(true, 99);
|
TestTriBool<TriBool<upx_uint32_t> >::test(false);
|
||||||
TestTriBool<TriBool<upx_int8_t, 2> >::test(true, 99990);
|
TestTriBool<TriBool<upx_int64_t> >::test(false);
|
||||||
TestTriBool<TriBool<upx_uint8_t, 2> >::test(true, 99991);
|
TestTriBool<TriBool<upx_uint64_t> >::test(false);
|
||||||
TestTriBool<TriBool<upx_int16_t, 2> >::test(true, 99992);
|
TestTriBool<TriBool<upx_int8_t, true> >::test(true);
|
||||||
TestTriBool<TriBool<upx_uint16_t, 2> >::test(true, 99993);
|
TestTriBool<TriBool<upx_uint8_t, true> >::test(true);
|
||||||
TestTriBool<TriBool<upx_int32_t, 2> >::test(true, 99994);
|
TestTriBool<TriBool<upx_int16_t, true> >::test(true);
|
||||||
TestTriBool<TriBool<upx_uint32_t, 2> >::test(true, 99995);
|
TestTriBool<TriBool<upx_uint16_t, true> >::test(true);
|
||||||
TestTriBool<TriBool<upx_int64_t, 2> >::test(true, 99996);
|
TestTriBool<TriBool<upx_int32_t, true> >::test(true);
|
||||||
TestTriBool<TriBool<upx_uint64_t, 2> >::test(true, 99997);
|
TestTriBool<TriBool<upx_uint32_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_int64_t, true> >::test(true);
|
||||||
|
TestTriBool<TriBool<upx_uint64_t, true> >::test(true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* vim:set ts=4 sw=4 et: */
|
/* vim:set ts=4 sw=4 et: */
|
||||||
|
|||||||
+2
-2
@@ -170,8 +170,8 @@ struct Options final {
|
|||||||
struct {
|
struct {
|
||||||
int compress_exports;
|
int compress_exports;
|
||||||
int compress_icons;
|
int compress_icons;
|
||||||
upx::TriBool<upx_int8_t, 2> compress_resources;
|
upx::TriBool<upx_int8_t, true> compress_resources;
|
||||||
upx::TriBool<upx_int8_t, 2> compress_rt[25]; // 25 == RT_LAST
|
upx::TriBool<upx_int8_t, true> compress_rt[25]; // 25 == RT_LAST
|
||||||
int strip_relocs;
|
int strip_relocs;
|
||||||
const char *keep_resource;
|
const char *keep_resource;
|
||||||
} win32_pe;
|
} win32_pe;
|
||||||
|
|||||||
+1
-2
@@ -2974,8 +2974,7 @@ tribool PackLinuxElf64::canUnpack() // bool, except -1: format known, but not pa
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
tribool
|
tribool PackLinuxElf64::canPack()
|
||||||
PackLinuxElf64::canPack()
|
|
||||||
{
|
{
|
||||||
union {
|
union {
|
||||||
unsigned char buf[MAX_ELF_HDR_64];
|
unsigned char buf[MAX_ELF_HDR_64];
|
||||||
|
|||||||
+7
-6
@@ -109,23 +109,23 @@ constexpr bool string_ge(const char *a, const char *b) { return !string_lt(a, b)
|
|||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
// TriBool - tri-state bool
|
// TriBool - tri-state bool
|
||||||
// an enum with an underlying type and 3 values
|
// an enum with an underlying type and 3 values
|
||||||
// bool() checks for > 0, so ThirdValue determines if Third is false or true
|
// IsThirdTrue determines if Third is false or true
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
template <class T = int, T ThirdValue = -1> // ThirdValue is false by default
|
template <class T = int, bool IsThirdTrue = false> // Third is false by default
|
||||||
struct TriBool final {
|
struct TriBool final {
|
||||||
// types
|
// types
|
||||||
typedef T underlying_type;
|
typedef T underlying_type;
|
||||||
static_assert(std::is_integral_v<underlying_type>);
|
static_assert(std::is_integral_v<underlying_type>);
|
||||||
typedef decltype(T(0) + T(0)) promoted_type;
|
typedef decltype(T(0) + T(0)) promoted_type;
|
||||||
static_assert(std::is_integral_v<promoted_type>);
|
static_assert(std::is_integral_v<promoted_type>);
|
||||||
static_assert(ThirdValue != 0 && ThirdValue != 1);
|
enum value_type : underlying_type { False = 0, True = 1, Third = 2 };
|
||||||
enum value_type : underlying_type { False = 0, True = 1, Third = ThirdValue };
|
|
||||||
static_assert(sizeof(value_type) == sizeof(underlying_type));
|
static_assert(sizeof(value_type) == sizeof(underlying_type));
|
||||||
static_assert(sizeof(underlying_type) <= sizeof(promoted_type));
|
static_assert(sizeof(underlying_type) <= sizeof(promoted_type));
|
||||||
// constructors
|
// constructors
|
||||||
forceinline constexpr TriBool() noexcept {}
|
forceinline constexpr TriBool() noexcept {}
|
||||||
forceinline constexpr TriBool(value_type x) noexcept : value(x) {}
|
forceinline constexpr TriBool(value_type x) noexcept : value(x) {}
|
||||||
|
// permissive, converts all other values to Third!!
|
||||||
constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Third)) {}
|
constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Third)) {}
|
||||||
#if __cplusplus >= 202002L
|
#if __cplusplus >= 202002L
|
||||||
forceinline constexpr ~TriBool() noexcept = default;
|
forceinline constexpr ~TriBool() noexcept = default;
|
||||||
@@ -133,8 +133,9 @@ struct TriBool final {
|
|||||||
forceinline ~TriBool() noexcept = default;
|
forceinline ~TriBool() noexcept = default;
|
||||||
#endif
|
#endif
|
||||||
// explicit conversion to bool
|
// explicit conversion to bool
|
||||||
// checks for > 0, so ThirdValue determines if Third is false (the default) or true
|
explicit constexpr operator bool() const noexcept {
|
||||||
explicit constexpr operator bool() const noexcept { return value > False; }
|
return IsThirdTrue ? (value != False) : (value == True);
|
||||||
|
}
|
||||||
// query; this is NOT the same as operator bool()
|
// query; this is NOT the same as operator bool()
|
||||||
constexpr bool isStrictFalse() const noexcept { return value == False; }
|
constexpr bool isStrictFalse() const noexcept { return value == False; }
|
||||||
constexpr bool isStrictTrue() const noexcept { return value == True; }
|
constexpr bool isStrictTrue() const noexcept { return value == True; }
|
||||||
|
|||||||
Reference in New Issue
Block a user