all: minor updates
This commit is contained in:
@@ -287,6 +287,37 @@ TEST_CASE("MemBuffer") {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("MemBuffer global overloads") {
|
||||
MemBuffer mb(1);
|
||||
MemBuffer mb4(4);
|
||||
mb.clear();
|
||||
mb4.clear();
|
||||
CHECK(memcmp(mb, "\x00", 1) == 0);
|
||||
CHECK_THROWS(memcmp(mb, "\x00\x00", 2));
|
||||
CHECK_THROWS(memcmp("\x00\x00", mb, 2));
|
||||
CHECK_THROWS(memcmp(mb, mb4, 2));
|
||||
CHECK_THROWS(memcmp(mb4, mb, 2));
|
||||
CHECK_NOTHROW(memset(mb, 255, 1));
|
||||
CHECK_THROWS(memset(mb, 254, 2));
|
||||
CHECK(mb[0] == 255);
|
||||
CHECK_THROWS(get_be16(mb));
|
||||
CHECK_THROWS(get_be32(mb));
|
||||
CHECK_THROWS(get_be64(mb));
|
||||
CHECK_THROWS(get_le16(mb));
|
||||
CHECK_THROWS(get_le32(mb));
|
||||
CHECK_THROWS(get_le64(mb));
|
||||
CHECK_NOTHROW(get_be16(mb4));
|
||||
CHECK_NOTHROW(get_be32(mb4));
|
||||
CHECK_THROWS(get_be64(mb4));
|
||||
CHECK_NOTHROW(get_le16(mb4));
|
||||
CHECK_NOTHROW(get_le32(mb4));
|
||||
CHECK_THROWS(get_le64(mb4));
|
||||
CHECK_NOTHROW(set_be32(mb4, 0));
|
||||
CHECK_THROWS(set_be64(mb4, 0));
|
||||
CHECK_NOTHROW(set_le32(mb4, 0));
|
||||
CHECK_THROWS(set_le64(mb4, 0));
|
||||
}
|
||||
|
||||
TEST_CASE("MemBuffer unused") {
|
||||
MemBuffer mb;
|
||||
CHECK(mb.raw_ptr() == nullptr);
|
||||
|
||||
+57
-34
@@ -27,19 +27,20 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
/*************************************************************************
|
||||
// A MemBuffer allocates memory on the heap, and automatically
|
||||
// gets destructed when leaving scope or on exceptions.
|
||||
|
||||
/*************************************************************************
|
||||
// provides some base functionality for treating a MemBuffer as a pointer
|
||||
**************************************************************************/
|
||||
|
||||
// provides some base functionality for treating a MemBuffer as a pointer
|
||||
template <class T>
|
||||
class MemBufferBase {
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef typename std::add_lvalue_reference<T>::type reference;
|
||||
typedef typename std::add_pointer<T>::type pointer;
|
||||
typedef unsigned size_type;
|
||||
typedef unsigned size_type; // limited by UPX_RSIZE_MAX
|
||||
|
||||
protected:
|
||||
pointer ptr;
|
||||
@@ -79,8 +80,61 @@ public: // raw access
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
private:
|
||||
// disable taking the address => force passing by reference
|
||||
// [I'm not too sure about this design decision, but we can always allow it if needed]
|
||||
MemBufferBase<T> *operator&() const DELETED_FUNCTION;
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// MemBufferBase global overloads
|
||||
**************************************************************************/
|
||||
|
||||
// global operators
|
||||
#if ALLOW_INT_PLUS_MEMBUFFER
|
||||
// rewrite "n + membuffer" to "membuffer + n" so that this will get checked above
|
||||
template <class T, class U>
|
||||
inline typename std::enable_if<std::is_integral<U>::value, typename MemBufferBase<T>::pointer>::type
|
||||
operator+(U n, const MemBufferBase<T> &mbb) {
|
||||
return mbb + n;
|
||||
}
|
||||
#else
|
||||
// not allowed
|
||||
template <class T, class U>
|
||||
inline typename std::enable_if<std::is_integral<U>::value, typename MemBufferBase<T>::pointer>::type
|
||||
operator+(U n, const MemBufferBase<T> &mbb) DELETED_FUNCTION;
|
||||
#endif
|
||||
|
||||
// raw_bytes overload
|
||||
template <class T>
|
||||
inline typename MemBufferBase<T>::pointer raw_bytes(const MemBufferBase<T> &mbb,
|
||||
size_t size_in_bytes) {
|
||||
return mbb.raw_bytes(size_in_bytes);
|
||||
}
|
||||
template <class T>
|
||||
inline typename MemBufferBase<T>::pointer raw_index_bytes(const MemBufferBase<T> &mbb, size_t index,
|
||||
size_t size_in_bytes) {
|
||||
typedef typename MemBufferBase<T>::element_type element_type;
|
||||
return mbb.raw_bytes(mem_size(sizeof(element_type), index, size_in_bytes)) + index;
|
||||
}
|
||||
|
||||
#if 1
|
||||
// some more global overloads using a checked raw_bytes() call
|
||||
#define XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION(A, B, RType) \
|
||||
typename std::enable_if<std::is_same<A, B>::value, RType>::type
|
||||
#define XSPAN_FWD_C_IS_MEMBUFFER 1
|
||||
#define C MemBufferBase
|
||||
#include "xspan_fwd.h"
|
||||
#undef C
|
||||
#undef XSPAN_FWD_C_IS_MEMBUFFER
|
||||
#undef XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION
|
||||
#endif
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
class MemBuffer final : public MemBufferBase<byte> {
|
||||
public:
|
||||
inline MemBuffer() noexcept : MemBufferBase<byte>() {}
|
||||
@@ -147,37 +201,6 @@ private:
|
||||
#endif
|
||||
// disable dynamic allocation
|
||||
ACC_CXX_DISABLE_NEW_DELETE
|
||||
|
||||
// disable taking the address => force passing by reference
|
||||
// [I'm not too sure about this design decision, but we can always allow it if needed]
|
||||
MemBuffer *operator&() const DELETED_FUNCTION;
|
||||
};
|
||||
|
||||
// raw_bytes overload
|
||||
template <class T>
|
||||
inline typename MemBufferBase<T>::pointer raw_bytes(const MemBufferBase<T> &mbb,
|
||||
size_t size_in_bytes) {
|
||||
return mbb.raw_bytes(size_in_bytes);
|
||||
}
|
||||
template <class T>
|
||||
inline typename MemBufferBase<T>::pointer raw_index_bytes(const MemBufferBase<T> &mbb, size_t index,
|
||||
size_t size_in_bytes) {
|
||||
typedef typename MemBufferBase<T>::element_type element_type;
|
||||
return mbb.raw_bytes(mem_size(sizeof(element_type), index, size_in_bytes)) + index;
|
||||
}
|
||||
|
||||
// global operators
|
||||
#if ALLOW_INT_PLUS_MEMBUFFER
|
||||
// rewrite "n + membuffer" to "membuffer + n" so that this will get checked above
|
||||
template <class T, class U>
|
||||
inline typename std::enable_if<std::is_integral<U>::value, typename MemBufferBase<T>::pointer>::type
|
||||
operator+(U n, const MemBufferBase<T> &mbb) {
|
||||
return mbb + n;
|
||||
}
|
||||
#else
|
||||
template <class T, class U>
|
||||
inline typename std::enable_if<std::is_integral<U>::value, typename MemBufferBase<T>::pointer>::type
|
||||
operator+(U n, const MemBufferBase<T> &mbb) DELETED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
|
||||
+10
-6
@@ -31,21 +31,23 @@
|
||||
template <class T, class U> \
|
||||
inline XSPAN_REQUIRES_CONVERTIBLE_ANY_DIRECTION(T, U, RType)
|
||||
|
||||
#ifndef XSPAN_FWD_C_IS_MEMBUFFER
|
||||
template <class T, class U>
|
||||
inline typename std::enable_if<std::is_integral<U>::value, void *>::type operator+(U, const C<T> &)
|
||||
DELETED_FUNCTION;
|
||||
#endif // XSPAN_FWD_C_IS_MEMBUFFER
|
||||
|
||||
/*************************************************************************
|
||||
// overloads for standard functions
|
||||
**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
inline void *memchr(const C<T> &a, int c, size_t n) {
|
||||
return memchr(a.raw_bytes(n), c, n);
|
||||
inline void *memchr(const C<T> &a, int v, size_t n) {
|
||||
return memchr(a.raw_bytes(n), v, n);
|
||||
}
|
||||
template <class T>
|
||||
inline const void *memchr(const C<const T> &a, int c, size_t n) {
|
||||
return memchr(a.raw_bytes(n), c, n);
|
||||
inline const void *memchr(const C<const T> &a, int v, size_t n) {
|
||||
return memchr(a.raw_bytes(n), v, n);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -115,8 +117,8 @@ XSPAN_FWD_TU(void *) memmove(const C<T> &a, const E<U> &b, size_t n) {
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
inline void *memset(const C<T> &a, int c, size_t n) {
|
||||
return memset(a.raw_bytes(n), c, n);
|
||||
inline void *memset(const C<T> &a, int v, size_t n) {
|
||||
return memset(a.raw_bytes(n), v, n);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
@@ -255,6 +257,7 @@ void set_le64(const C<T> &a, upx_uint64_t v) {
|
||||
return set_le64(a.raw_bytes(8), v);
|
||||
}
|
||||
|
||||
#ifndef XSPAN_FWD_C_IS_MEMBUFFER
|
||||
template <class T>
|
||||
inline C<T> operator+(const C<T> &a, const BE16 &v) {
|
||||
return a + unsigned(v);
|
||||
@@ -288,6 +291,7 @@ template <class T>
|
||||
inline C<T> operator-(const C<T> &a, const LE32 &v) {
|
||||
return a - unsigned(v);
|
||||
}
|
||||
#endif // XSPAN_FWD_C_IS_MEMBUFFER
|
||||
|
||||
template <class T>
|
||||
typename std::enable_if<sizeof(T) == 1, upx_rsize_t>::type upx_safe_strlen(const C<T> &a) {
|
||||
|
||||
Reference in New Issue
Block a user