src: create util/cxxlib.h
This commit is contained in:
-107
@@ -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
|
||||
**************************************************************************/
|
||||
|
||||
Reference in New Issue
Block a user