src: create util/cxxlib.h

This commit is contained in:
Markus F.X.J. Oberhumer
2023-08-16 10:05:59 +02:00
parent 394cd77bec
commit 8975e2a6b5
15 changed files with 471 additions and 358 deletions
-107
View File
@@ -130,113 +130,6 @@ void upx_memswap(void *a, void *b, size_t n);
void upx_stable_sort(void *array, size_t n, size_t element_size,
int (*compare)(const void *, const void *));
/*************************************************************************
// OwningPointer(T)
// simple pointer type alias to explicitly mark ownership of objects; purely
// cosmetic to improve source code readability, no real functionality
**************************************************************************/
#if 0
// this works
#define OwningPointer(T) T *
#elif !(DEBUG)
// this also works
template <class T>
using OwningPointer = T *;
#define OwningPointer(T) OwningPointer<T>
#else
// also works: a trivial class with just a number of no-ops
template <class T>
struct OwningPointer final {
static_assert(std::is_class_v<T>); // UPX convention
typedef typename std::add_lvalue_reference<T>::type reference;
typedef typename std::add_lvalue_reference<const T>::type const_reference;
typedef typename std::add_pointer<T>::type pointer;
typedef typename std::add_pointer<const T>::type const_pointer;
pointer ptr;
inline OwningPointer(pointer p) noexcept : ptr(p) {}
inline operator pointer() noexcept { return ptr; }
inline operator const_pointer() const noexcept { return ptr; }
inline reference operator*() noexcept { return *ptr; }
inline const_reference operator*() const noexcept { return *ptr; }
inline pointer operator->() noexcept { return ptr; }
inline const_pointer operator->() const noexcept { return ptr; }
};
// must overload mem_clear()
template <class T>
inline void mem_clear(OwningPointer<T> object) noexcept {
mem_clear((T *) object);
}
#define OwningPointer(T) OwningPointer<T>
#endif
template <class T>
inline void owner_delete(OwningPointer(T)(&object)) noexcept {
static_assert(std::is_class_v<T>); // UPX convention
static_assert(std::is_nothrow_destructible_v<T>);
if (object != nullptr) {
delete (T *) object;
object = nullptr;
}
}
// disable some overloads
#if defined(__clang__) || __GNUC__ != 7
template <class T>
inline void owner_delete(T (&array)[]) noexcept DELETED_FUNCTION;
#endif
template <class T, size_t N>
inline void owner_delete(T (&array)[N]) noexcept DELETED_FUNCTION;
/*************************************************************************
// TriBool - tri-state bool
**************************************************************************/
template <class T = int, T TOther = -1> // an enum with an underlying type and 3 values
class TriBool {
public:
// types
typedef T underlying_type;
static_assert(std::is_integral_v<underlying_type>);
typedef decltype(T(0) + T(0)) promoted_type;
static_assert(std::is_integral_v<promoted_type>);
static_assert(TOther != 0 && TOther != 1);
enum value_type : underlying_type { False = 0, True = 1, Other = TOther };
// constructors
forceinline constexpr TriBool() noexcept = default;
forceinline ~TriBool() noexcept = default;
constexpr TriBool(value_type x) noexcept : value(x) {}
constexpr TriBool(promoted_type x) noexcept : value(x == 0 ? False : (x == 1 ? True : Other)) {}
// access
constexpr value_type getValue() const noexcept { return value; }
// checks for > 0, so TOther determines if Other is false (the default) or true
explicit constexpr operator bool() const noexcept { return value > False; }
// query; this is NOT the same as operator bool()
constexpr bool isStrictFalse() const noexcept { return value == False; }
constexpr bool isStrictTrue() const noexcept { return value == True; }
constexpr bool isStrictBool() const noexcept { return value == False || value == True; }
constexpr bool isOther() const noexcept { return value != False && value != True; }
// "other" can mean many things, depending on usage context, so provide some alternative names:
// constexpr bool isDefault() const noexcept { return isOther(); } // might be misleading
constexpr bool isIndeterminate() const noexcept { return isOther(); }
constexpr bool isUndecided() const noexcept { return isOther(); }
// constexpr bool isUnset() const noexcept { return isOther(); } // might be misleading
constexpr bool operator==(TriBool other) const noexcept { return value == other.value; }
constexpr bool operator==(value_type other) const noexcept { return value == other; }
constexpr bool operator==(promoted_type other) const noexcept { return value == other; }
protected:
// value
value_type value = False;
};
typedef TriBool<> tribool;
/*************************************************************************
// misc. support functions
**************************************************************************/