src: major cleanups, introduce new eXtended Span class
- initial minimally invasive eXtended Span implementation - rename ptr_diff to ptr_diff_bytes - move some files to util subdir - lots of cleanups - start using the new checked pointers - this needs some real-world testing
This commit is contained in:
@@ -0,0 +1,209 @@
|
||||
/* xspan -- a minimally invasive checked memory smart pointer
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2022 Markus Franz Xaver Johannes Oberhumer
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer
|
||||
<markus@oberhumer.com>
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
SPAN_NAMESPACE_BEGIN
|
||||
|
||||
/*************************************************************************
|
||||
// Ptr
|
||||
**************************************************************************/
|
||||
|
||||
template <class T>
|
||||
struct Ptr {
|
||||
private:
|
||||
#define CSelf Ptr
|
||||
typedef CSelf<T> Self;
|
||||
|
||||
public:
|
||||
// befriend all
|
||||
template <class>
|
||||
friend struct CSelf;
|
||||
|
||||
typedef T element_type;
|
||||
typedef typename std::add_lvalue_reference<T>::type reference;
|
||||
// typedef T *pointer;
|
||||
typedef typename std::add_pointer<T>::type pointer;
|
||||
|
||||
private:
|
||||
pointer ptr;
|
||||
|
||||
// enforce config invariants at constructor time - static functions
|
||||
static __acc_forceinline pointer makePtr(pointer p) { return p; }
|
||||
// inverse logic for ensuring valid pointers from existing objets
|
||||
__acc_forceinline pointer ensurePtr() const { return ptr; }
|
||||
// debug
|
||||
__acc_forceinline void assertInvariants() const {}
|
||||
|
||||
public:
|
||||
#if SPAN_CONFIG_ENABLE_IMPLICIT_CONVERSION || 1
|
||||
operator pointer() const { return ptr; }
|
||||
#endif
|
||||
|
||||
inline ~CSelf() {}
|
||||
inline CSelf() {}
|
||||
|
||||
// constructors from pointers
|
||||
CSelf(pointer p) : ptr(makePtr(p)) {}
|
||||
template <class U>
|
||||
CSelf(U *p, SPAN_REQUIRES_CONVERTIBLE_A) : ptr(makePtr(p)) {}
|
||||
|
||||
// constructors
|
||||
CSelf(const Self &other) : ptr(other.ptr) {}
|
||||
template <class U>
|
||||
CSelf(const CSelf<U> &other, SPAN_REQUIRES_CONVERTIBLE_A) : ptr(other.ptr) {}
|
||||
|
||||
Self &assign(const Self &other) {
|
||||
assertInvariants();
|
||||
other.assertInvariants();
|
||||
ptr = other.ptr;
|
||||
assertInvariants();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// assignment
|
||||
Self &operator=(const Self &other) { return assign(other); }
|
||||
|
||||
template <class U>
|
||||
SPAN_REQUIRES_CONVERTIBLE_R(Self &)
|
||||
operator=(U *other) {
|
||||
assert(0);
|
||||
return assign(Self(other));
|
||||
}
|
||||
|
||||
// FIXME: this is not called !!
|
||||
template <class U>
|
||||
SPAN_REQUIRES_CONVERTIBLE_R(Self &)
|
||||
operator=(const CSelf<U> &other) {
|
||||
assert(0);
|
||||
return assign(Self(other));
|
||||
}
|
||||
|
||||
// comparision
|
||||
|
||||
bool operator==(pointer other) const { return ptr == other; }
|
||||
template <class U>
|
||||
SPAN_REQUIRES_CONVERTIBLE_R(bool)
|
||||
operator==(U *other) const {
|
||||
return ptr == other;
|
||||
}
|
||||
template <class U>
|
||||
SPAN_REQUIRES_CONVERTIBLE_R(bool)
|
||||
operator==(const Ptr<U> &other) const {
|
||||
return ptr == other.ptr;
|
||||
}
|
||||
|
||||
// dereference
|
||||
reference operator*() const { return *check_deref(ptr); }
|
||||
|
||||
// array access
|
||||
reference operator[](ptrdiff_t i) const { return *check_deref(ptr, i); }
|
||||
|
||||
// arrow operator
|
||||
pointer operator->() const { return check_deref(ptr); }
|
||||
|
||||
Self &operator++() {
|
||||
ptr = check_add(ptr, 1);
|
||||
return *this;
|
||||
}
|
||||
Self operator++(int) {
|
||||
Self tmp = *this;
|
||||
++*this;
|
||||
return tmp;
|
||||
}
|
||||
Self &operator--() {
|
||||
ptr = check_add(ptr, -1);
|
||||
return *this;
|
||||
}
|
||||
Self operator--(int) {
|
||||
Self tmp = *this;
|
||||
--*this;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
Self &operator+=(ptrdiff_t n) {
|
||||
ptr = check_add(ptr, n);
|
||||
return *this;
|
||||
}
|
||||
Self &operator-=(ptrdiff_t n) {
|
||||
ptr = check_add(ptr, -n);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Self operator+(ptrdiff_t n) const {
|
||||
pointer p = check_add(ptr, n);
|
||||
return Self(p);
|
||||
}
|
||||
Self operator-(ptrdiff_t n) const {
|
||||
pointer p = check_add(ptr, -n);
|
||||
return Self(p);
|
||||
}
|
||||
|
||||
#ifdef UPX_VERSION_HEX
|
||||
CSelf(MemBuffer &mb) : ptr((pointer) membuffer_get_void_ptr(mb)) {}
|
||||
Self &operator=(MemBuffer &mb) { return assign(Self(mb)); }
|
||||
#endif
|
||||
|
||||
private:
|
||||
__acc_forceinline pointer check_deref(pointer p) const { return p; }
|
||||
__acc_forceinline pointer check_deref(pointer p, ptrdiff_t n) const { return p + n; }
|
||||
__acc_forceinline pointer check_add(pointer p, ptrdiff_t n) const { return p + n; }
|
||||
|
||||
public: // raw access
|
||||
pointer raw_ptr() const { return ptr; }
|
||||
|
||||
pointer raw_bytes(size_t bytes) const {
|
||||
assertInvariants();
|
||||
if (bytes > 0) {
|
||||
if __acc_cte (ptr == nullptr)
|
||||
span_fail_nullptr();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#undef CSelf
|
||||
};
|
||||
|
||||
template <class T>
|
||||
inline T *raw_bytes(const Ptr<T> &a, size_t size_in_bytes) {
|
||||
return a.raw_bytes(size_in_bytes);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
SPAN_NAMESPACE_END
|
||||
|
||||
#if 1
|
||||
|
||||
#define C SPAN_NS(Ptr)
|
||||
#include "xspan_fwd.h"
|
||||
#undef C
|
||||
|
||||
#endif
|
||||
|
||||
/* vim:set ts=4 sw=4 et: */
|
||||
Reference in New Issue
Block a user