mirror of
https://github.com/libretro/bsnes-libretro-cplusplus98.git
synced 2025-04-12 15:13:34 +00:00
nall::
This commit is contained in:
parent
eed83fa4ff
commit
4655c2d469
@ -4,8 +4,14 @@
|
||||
#include <nall/concept.hpp>
|
||||
|
||||
#undef foreach
|
||||
#define foreach(iter, object) \
|
||||
|
||||
#define foreach2(iter, object) foreach3(iter, object, foreach_counter)
|
||||
#define foreach3(iter, object, foreach_counter) \
|
||||
for(unsigned foreach_counter = 0, foreach_limit = container_size(object), foreach_once = 0, foreach_broken = 0; foreach_counter < foreach_limit && foreach_broken == 0; foreach_counter++, foreach_once = 0) \
|
||||
for(typeof(object[0]) &iter = object[foreach_counter]; foreach_once == 0 && (foreach_broken = 1); foreach_once++, foreach_broken = 0)
|
||||
|
||||
#define foreach_impl(...) foreach_decl(__VA_ARGS__, foreach3(__VA_ARGS__), foreach2(__VA_ARGS__), foreach_too_few_arguments)
|
||||
#define foreach_decl(_1, _2, _3, N, ...) N
|
||||
#define foreach(...) foreach_impl(__VA_ARGS__)
|
||||
|
||||
#endif
|
||||
|
32
nall/public_cast.hpp
Normal file
32
nall/public_cast.hpp
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef NALL_PUBLIC_CAST_HPP
|
||||
#define NALL_PUBLIC_CAST_HPP
|
||||
|
||||
//this is a proof-of-concept-*only* C++ access-privilege elevation exploit.
|
||||
//this code is 100% legal C++, per C++98 section 14.7.2 paragraph 8:
|
||||
//"access checking rules do not apply to names in explicit instantiations."
|
||||
//usage example:
|
||||
|
||||
//struct N { typedef void (Class::*)(); };
|
||||
//template class public_cast<N, &Class::Reference>;
|
||||
//(class.*public_cast<N>::value);
|
||||
|
||||
//Class::Reference may be public, protected or private
|
||||
//Class::Reference may be a function, object or variable
|
||||
|
||||
namespace nall {
|
||||
template<typename T, typename T::type... P> struct public_cast;
|
||||
|
||||
template<typename T> struct public_cast<T> {
|
||||
static typename T::type value;
|
||||
};
|
||||
|
||||
template<typename T> typename T::type public_cast<T>::value;
|
||||
|
||||
template<typename T, typename T::type P> struct public_cast<T, P> {
|
||||
static typename T::type value;
|
||||
};
|
||||
|
||||
template<typename T, typename T::type P> typename T::type public_cast<T, P>::value = public_cast<T>::value = P;
|
||||
}
|
||||
|
||||
#endif
|
103
nall/reference_array.hpp
Normal file
103
nall/reference_array.hpp
Normal file
@ -0,0 +1,103 @@
|
||||
#ifndef NALL_REFERENCE_ARRAY_HPP
|
||||
#define NALL_REFERENCE_ARRAY_HPP
|
||||
|
||||
#include <type_traits>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/concept.hpp>
|
||||
|
||||
namespace nall {
|
||||
template<typename T> struct reference_array {
|
||||
protected:
|
||||
typedef typename std::remove_reference<T>::type *Tptr;
|
||||
Tptr *pool;
|
||||
unsigned poolsize, buffersize;
|
||||
|
||||
public:
|
||||
unsigned size() const { return buffersize; }
|
||||
unsigned capacity() const { return poolsize; }
|
||||
|
||||
void reset() {
|
||||
if(pool) free(pool);
|
||||
pool = 0;
|
||||
poolsize = 0;
|
||||
buffersize = 0;
|
||||
}
|
||||
|
||||
void reserve(unsigned newsize) {
|
||||
if(newsize == poolsize) return;
|
||||
|
||||
pool = (Tptr*)realloc(pool, newsize * sizeof(T));
|
||||
poolsize = newsize;
|
||||
buffersize = min(buffersize, newsize);
|
||||
}
|
||||
|
||||
void resize(unsigned newsize) {
|
||||
if(newsize > poolsize) reserve(bit::round(newsize));
|
||||
buffersize = newsize;
|
||||
}
|
||||
|
||||
void append(const T data) {
|
||||
unsigned index = buffersize++;
|
||||
if(index >= poolsize) resize(index + 1);
|
||||
pool[index] = &data;
|
||||
}
|
||||
|
||||
template<typename... Args> reference_array(Args&... args) : pool(0), poolsize(0), buffersize(0) {
|
||||
construct(args...);
|
||||
}
|
||||
|
||||
~reference_array() {
|
||||
reset();
|
||||
}
|
||||
|
||||
reference_array& operator=(const reference_array &source) {
|
||||
if(pool) free(pool);
|
||||
buffersize = source.buffersize;
|
||||
poolsize = source.poolsize;
|
||||
pool = (Tptr*)malloc(sizeof(T) * poolsize);
|
||||
memcpy(pool, source.pool, sizeof(T) * buffersize);
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference_array& operator=(const reference_array &&source) {
|
||||
if(pool) free(pool);
|
||||
pool = source.pool;
|
||||
poolsize = source.poolsize;
|
||||
buffersize = source.buffersize;
|
||||
source.pool = 0;
|
||||
source.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline T operator[](unsigned index) {
|
||||
if(index >= buffersize) throw "reference_array[] out of bounds";
|
||||
return *pool[index];
|
||||
}
|
||||
|
||||
inline const T operator[](unsigned index) const {
|
||||
if(index >= buffersize) throw "reference_array[] out of bounds";
|
||||
return *pool[index];
|
||||
}
|
||||
|
||||
private:
|
||||
void construct() {
|
||||
}
|
||||
|
||||
void construct(const reference_array &source) {
|
||||
operator=(source);
|
||||
}
|
||||
|
||||
void construct(const reference_array &&source) {
|
||||
operator=(std::move(source));
|
||||
}
|
||||
|
||||
template<typename... Args> void construct(T data, Args&... args) {
|
||||
append(data);
|
||||
construct(args...);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct has_size<reference_array<T>> { enum { value = true }; };
|
||||
}
|
||||
|
||||
#endif
|
@ -71,7 +71,7 @@ namespace nall {
|
||||
|
||||
inline ~string();
|
||||
|
||||
inline bool readfile(const char*);
|
||||
inline bool readfile(const string&);
|
||||
inline string& replace (const char*, const char*);
|
||||
inline string& qreplace(const char*, const char*);
|
||||
|
||||
|
@ -69,8 +69,11 @@ inline intmax_t integer(const char *str) {
|
||||
intmax_t result = 0;
|
||||
bool negate = false;
|
||||
|
||||
//check for negation
|
||||
if(*str == '-') {
|
||||
//check for sign
|
||||
if(*str == '+') {
|
||||
negate = false;
|
||||
str++;
|
||||
} else if(*str == '-') {
|
||||
negate = true;
|
||||
str++;
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ string::~string() {
|
||||
if(data) free(data);
|
||||
}
|
||||
|
||||
bool string::readfile(const char *filename) {
|
||||
bool string::readfile(const string &filename) {
|
||||
assign("");
|
||||
|
||||
#if !defined(_WIN32)
|
||||
|
@ -50,10 +50,10 @@ inline string integer(intmax_t value) {
|
||||
result[x] = buffer[y];
|
||||
}
|
||||
|
||||
return result;
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
template<unsigned length> inline string linteger(intmax_t value) {
|
||||
template<unsigned length_> inline string linteger(intmax_t value) {
|
||||
bool negative = value < 0;
|
||||
if(negative) value = abs(value);
|
||||
|
||||
@ -68,7 +68,8 @@ template<unsigned length> inline string linteger(intmax_t value) {
|
||||
buffer[size++] = negative ? '-' : '+';
|
||||
buffer[size] = 0;
|
||||
|
||||
char result[length + 1];
|
||||
unsigned length = (length_ == 0 ? size : length_);
|
||||
char result[64];
|
||||
memset(result, ' ', length);
|
||||
result[length] = 0;
|
||||
|
||||
@ -76,10 +77,10 @@ template<unsigned length> inline string linteger(intmax_t value) {
|
||||
result[x] = buffer[y];
|
||||
}
|
||||
|
||||
return result;
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
template<unsigned length> inline string rinteger(intmax_t value) {
|
||||
template<unsigned length_> inline string rinteger(intmax_t value) {
|
||||
bool negative = value < 0;
|
||||
if(negative) value = abs(value);
|
||||
|
||||
@ -94,7 +95,8 @@ template<unsigned length> inline string rinteger(intmax_t value) {
|
||||
buffer[size++] = negative ? '-' : '+';
|
||||
buffer[size] = 0;
|
||||
|
||||
char result[length + 1];
|
||||
unsigned length = (length_ == 0 ? size : length_);
|
||||
char result[64];
|
||||
memset(result, ' ', length);
|
||||
result[length] = 0;
|
||||
|
||||
@ -102,7 +104,7 @@ template<unsigned length> inline string rinteger(intmax_t value) {
|
||||
result[x] = buffer[y];
|
||||
}
|
||||
|
||||
return result;
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
inline string decimal(uintmax_t value) {
|
||||
@ -124,10 +126,10 @@ inline string decimal(uintmax_t value) {
|
||||
result[x] = buffer[y];
|
||||
}
|
||||
|
||||
return &result[0];
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
template<unsigned length> inline string ldecimal(uintmax_t value) {
|
||||
template<unsigned length_> inline string ldecimal(uintmax_t value) {
|
||||
char buffer[64];
|
||||
unsigned size = 0;
|
||||
|
||||
@ -138,7 +140,8 @@ template<unsigned length> inline string ldecimal(uintmax_t value) {
|
||||
} while(value);
|
||||
buffer[size] = 0;
|
||||
|
||||
char result[length + 1];
|
||||
unsigned length = (length_ == 0 ? size : length_);
|
||||
char result[64];
|
||||
memset(result, ' ', length);
|
||||
result[length] = 0;
|
||||
|
||||
@ -146,10 +149,10 @@ template<unsigned length> inline string ldecimal(uintmax_t value) {
|
||||
result[x] = buffer[y];
|
||||
}
|
||||
|
||||
return result;
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
template<unsigned length> inline string rdecimal(uintmax_t value) {
|
||||
template<unsigned length_> inline string rdecimal(uintmax_t value) {
|
||||
char buffer[64];
|
||||
unsigned size = 0;
|
||||
|
||||
@ -160,7 +163,8 @@ template<unsigned length> inline string rdecimal(uintmax_t value) {
|
||||
} while(value);
|
||||
buffer[size] = 0;
|
||||
|
||||
char result[length + 1];
|
||||
unsigned length = (length_ == 0 ? size : length_);
|
||||
char result[64];
|
||||
memset(result, ' ', length);
|
||||
result[length] = 0;
|
||||
|
||||
@ -168,53 +172,51 @@ template<unsigned length> inline string rdecimal(uintmax_t value) {
|
||||
result[x] = buffer[y];
|
||||
}
|
||||
|
||||
return result;
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
template<unsigned length> inline string hex(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
template<unsigned length_> inline string hex(uintmax_t value) {
|
||||
char buffer[64];
|
||||
unsigned size = 0;
|
||||
|
||||
//render string backwards, as we do not know its length yet
|
||||
do {
|
||||
unsigned n = value & 15;
|
||||
output[offset++] = n < 10 ? '0' + n : 'a' + n - 10;
|
||||
buffer[size++] = n < 10 ? '0' + n : 'a' + n - 10;
|
||||
value >>= 4;
|
||||
} while(value);
|
||||
|
||||
while(offset < length) output[offset++] = '0';
|
||||
output[offset--] = 0;
|
||||
unsigned length = (length_ == 0 ? size : length_);
|
||||
char result[64];
|
||||
memset(result, '0', length);
|
||||
result[length] = 0;
|
||||
|
||||
//reverse the string in-place
|
||||
for(unsigned i = 0; i < (offset + 1) >> 1; i++) {
|
||||
char temp = output[i];
|
||||
output[i] = output[offset - i];
|
||||
output[offset - i] = temp;
|
||||
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
|
||||
result[x] = buffer[y];
|
||||
}
|
||||
|
||||
return output;
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
template<unsigned length> inline string binary(uintmax_t value) {
|
||||
string output;
|
||||
unsigned offset = 0;
|
||||
template<unsigned length_> inline string binary(uintmax_t value) {
|
||||
char buffer[256];
|
||||
unsigned size = 0;
|
||||
|
||||
do {
|
||||
unsigned n = value & 1;
|
||||
output[offset++] = '0' + n;
|
||||
buffer[size++] = '0' + n;
|
||||
value >>= 1;
|
||||
} while(value);
|
||||
|
||||
while(offset < length) output[offset++] = '0';
|
||||
output[offset--] = 0;
|
||||
unsigned length = (length_ == 0 ? size : length_);
|
||||
char result[64];
|
||||
memset(result, '0', length);
|
||||
result[length] = 0;
|
||||
|
||||
for(unsigned i = 0; i < (offset + 1) >> 1; i++) {
|
||||
char temp = output[i];
|
||||
output[i] = output[offset - i];
|
||||
output[offset - i] = temp;
|
||||
for(signed x = length - 1, y = 0; x >= 0 && y < size; x--, y++) {
|
||||
result[x] = buffer[y];
|
||||
}
|
||||
|
||||
return output;
|
||||
return (const char*)result;
|
||||
}
|
||||
|
||||
//using sprintf is certainly not the most ideal method to convert
|
||||
|
Loading…
x
Reference in New Issue
Block a user