diff --git a/src/conf.h b/src/conf.h index 8a60d0e7..3bf9883f 100644 --- a/src/conf.h +++ b/src/conf.h @@ -173,6 +173,7 @@ typedef upx_int64_t upx_off_t; #else #define noinline __acc_noinline #endif +#define forceinline_constexpr forceinline constexpr #define likely __acc_likely #define unlikely __acc_unlikely #define very_likely __acc_very_likely diff --git a/src/util/xspan.h b/src/util/xspan.h index a7825c8b..21c257c1 100644 --- a/src/util/xspan.h +++ b/src/util/xspan.h @@ -95,6 +95,11 @@ using XSPAN_NAMESPACE_NAME::raw_index_bytes; // overloaded for all classes #define XSPAN_P_VAR(type, var, first, ...) XSPAN_P(type) var((first), ##__VA_ARGS__) #define XSPAN_S_VAR(type, var, first, ...) XSPAN_S(type) var((first), ##__VA_ARGS__) +// cast to a different type (creates a new value) +#define XSPAN_0_CAST(type, var) ((var).type_cast()) +#define XSPAN_P_CAST(type, var) ((var).type_cast()) +#define XSPAN_S_CAST(type, var) ((var).type_cast()) + #elif WITH_XSPAN >= 1 // unchecked - just a no-op pointer wrapper, no extra functionality @@ -114,6 +119,11 @@ using XSPAN_NAMESPACE_NAME::raw_index_bytes; // overloaded for all classes #define XSPAN_P_VAR(type, var, first, ...) XSPAN_P(type) var((first)) #define XSPAN_S_VAR(type, var, first, ...) XSPAN_S(type) var((first)) +// cast to a different type (creates a new value) +#define XSPAN_0_CAST(type, var) ((var).type_cast()) +#define XSPAN_P_CAST(type, var) ((var).type_cast()) +#define XSPAN_S_CAST(type, var) ((var).type_cast()) + #else // WITH_XSPAN // unchecked regular pointers @@ -147,6 +157,11 @@ inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) noexcept { #define XSPAN_P_VAR(type, var, first, ...) type *var = XSPAN_P_MAKE(type, (first)) #define XSPAN_S_VAR(type, var, first, ...) type *var = XSPAN_S_MAKE(type, (first)) +// cast to a different type (creates a new value) +#define XSPAN_0_CAST(type, var) ((type *) (var)) +#define XSPAN_P_CAST(type, var) ((type *) (var)) +#define XSPAN_S_CAST(type, var) ((type *) (var)) + #endif // WITH_XSPAN /************************************************************************* @@ -166,6 +181,10 @@ inline R *xspan_make_helper__(R * /*dummy*/, MemBuffer &mb) noexcept { #define SPAN_0_VAR XSPAN_0_VAR #define SPAN_P_VAR XSPAN_P_VAR #define SPAN_S_VAR XSPAN_S_VAR +// cast to a different type (creates a new value) +#define SPAN_0_CAST XSPAN_0_CAST +#define SPAN_P_CAST XSPAN_P_CAST +#define SPAN_S_CAST XSPAN_S_CAST #endif /* vim:set ts=4 sw=4 et: */ diff --git a/src/util/xspan_fwd.h b/src/util/xspan_fwd.h index 82c6a6b5..752787d3 100644 --- a/src/util/xspan_fwd.h +++ b/src/util/xspan_fwd.h @@ -179,6 +179,11 @@ XSPAN_FWD_TU(unsigned) ptr_udiff_bytes(const C &a, const E &b) { #ifdef UPX_VERSION_HEX +template +inline unsigned upx_adler32(const C &a, unsigned n, unsigned adler = 1) { + return upx_adler32(a.raw_bytes(n), n, adler); +} + template unsigned get_ne16(const C &a) { return get_ne16(a.raw_bytes(2)); diff --git a/src/util/xspan_impl.h b/src/util/xspan_impl.h index 3dd60c76..c3cba4c8 100644 --- a/src/util/xspan_impl.h +++ b/src/util/xspan_impl.h @@ -53,11 +53,11 @@ void xspan_check_range(const void *ptr, const void *base, ptrdiff_t size_in_byte // help constructor to distinguish between number of elements and bytes struct XSpanCount final { - explicit forceinline constexpr XSpanCount(size_t n) noexcept : count(n) {} + explicit forceinline_constexpr XSpanCount(size_t n) noexcept : count(n) {} size_t count; // public }; struct XSpanSizeInBytes final { - explicit forceinline constexpr XSpanSizeInBytes(size_t bytes) noexcept : size_in_bytes(bytes) {} + explicit forceinline_constexpr XSpanSizeInBytes(size_t bytes) noexcept : size_in_bytes(bytes) {} size_t size_in_bytes; // public }; @@ -199,29 +199,22 @@ struct Ptr; class XSpanInternalDummyArgFake; // not implemented on purpose typedef XSpanInternalDummyArgFake *XSpanInternalDummyArg; #define XSpanInternalDummyArgInit nullptr -#elif 1 +#elif __cplusplus >= 201103L && 1 // use an enum struct XSpanInternalDummyArg final { enum DummyEnum {}; - explicit forceinline constexpr XSpanInternalDummyArg(DummyEnum &&) noexcept {} + explicit forceinline_constexpr XSpanInternalDummyArg(DummyEnum &&) noexcept {} }; #define XSpanInternalDummyArgInit \ (XSPAN_NS(XSpanInternalDummyArg)(XSPAN_NS(XSpanInternalDummyArg)::DummyEnum{})) #else // use a class with a private constructor struct XSpanInternalDummyArg final { - static forceinline constexpr XSpanInternalDummyArg make() noexcept { - return XSpanInternalDummyArg{}; + static forceinline_constexpr XSpanInternalDummyArg make() noexcept { + return XSpanInternalDummyArg(); } private: - explicit forceinline constexpr XSpanInternalDummyArg() noexcept {} -#if !(ACC_CC_MSC) // MSVC wants to use the copy and move constructors; correct or compiler bug? - // @COMPILER_BUG @MSVC_BUG - XSpanInternalDummyArg(const XSpanInternalDummyArg &) = delete; - XSpanInternalDummyArg(XSpanInternalDummyArg &&) noexcept = delete; - XSpanInternalDummyArg &operator=(const XSpanInternalDummyArg &) = delete; - XSpanInternalDummyArg &operator=(XSpanInternalDummyArg &&) noexcept = delete; -#endif + explicit forceinline_constexpr XSpanInternalDummyArg() noexcept {} }; #define XSpanInternalDummyArgInit \ (XSPAN_NS(XSpanInternalDummyArg)(XSPAN_NS(XSpanInternalDummyArg)::make())) diff --git a/src/util/xspan_impl_common.h b/src/util/xspan_impl_common.h index 1f55697c..1fb0120c 100644 --- a/src/util/xspan_impl_common.h +++ b/src/util/xspan_impl_common.h @@ -29,6 +29,7 @@ **************************************************************************/ #if CLANG_FORMAT_DUMMY_CLASS +template class CSelf { #endif @@ -68,7 +69,7 @@ private: xspan_check_range(ptr, base, size_in_bytes); } #else -forceinline constexpr void assertInvariants() const noexcept {} +forceinline_constexpr void assertInvariants() const noexcept {} #endif static inline pointer makeNotNull(pointer p) { @@ -272,7 +273,7 @@ public: Self &operator=(MemBuffer &mb) { return assign(Self(mb)); } #endif - Self subspan(ptrdiff_t offset, ptrdiff_t count) { + Self subspan(ptrdiff_t offset, ptrdiff_t count) const { pointer begin = check_add(ptr, offset); pointer end = check_add(begin, count); if (begin <= end) @@ -281,6 +282,14 @@ public: return Self(Unchecked, end, (begin - end) * sizeof(T), end); } + template + CSelf type_cast() const { + assertInvariants(); + typedef CSelf R; + return R(R::Unchecked, reinterpret_cast(ptr), size_in_bytes, + reinterpret_cast(base)); + } + bool operator==(pointer other) const { return ptr == other; } template XSPAN_REQUIRES_CONVERTIBLE_R(bool) diff --git a/src/util/xspan_impl_ptr.h b/src/util/xspan_impl_ptr.h index c5f04270..1abcd3f2 100644 --- a/src/util/xspan_impl_ptr.h +++ b/src/util/xspan_impl_ptr.h @@ -55,7 +55,7 @@ private: // inverse logic for ensuring valid pointers from existing objects inline pointer ensurePtr() const { return ptr; } // debug - forceinline constexpr void assertInvariants() const noexcept {} + forceinline_constexpr void assertInvariants() const noexcept {} public: #if XSPAN_CONFIG_ENABLE_IMPLICIT_CONVERSION || 1