mirror of
https://github.com/libretro/bsnes-libretro.git
synced 2024-11-27 02:50:32 +00:00
82293c95ae
byuu says: Changelog: - (u)int(max,ptr) abbreviations removed; use _t suffix now [didn't feel like they were contributing enough to be worth it] - cleaned up nall::integer,natural,real functionality - toInteger, toNatural, toReal for parsing strings to numbers - fromInteger, fromNatural, fromReal for creating strings from numbers - (string,Markup::Node,SQL-based-classes)::(integer,natural,real) left unchanged - template<typename T> numeral(T value, long padding, char padchar) -> string for print() formatting - deduces integer,natural,real based on T ... cast the value if you want to override - there still exists binary,octal,hex,pointer for explicit print() formatting - lstring -> string_vector [but using lstring = string_vector; is declared] - would be nice to remove the using lstring eventually ... but that'd probably require 10,000 lines of changes >_> - format -> string_format [no using here; format was too ambiguous] - using integer = Integer<sizeof(int)*8>; and using natural = Natural<sizeof(uint)*8>; declared - for consistency with boolean. These three are meant for creating zero-initialized values implicitly (various uses) - R65816::io() -> idle() and SPC700::io() -> idle() [more clear; frees up struct IO {} io; naming] - SFC CPU, PPU, SMP use struct IO {} io; over struct (Status,Registers) {} (status,registers); now - still some CPU::Status status values ... they didn't really fit into IO functionality ... will have to think about this more - SFC CPU, PPU, SMP now use step() exclusively instead of addClocks() calling into step() - SFC CPU joypad1_bits, joypad2_bits were unused; killed them - SFC PPU CGRAM moved into PPU::Screen; since nothing else uses it - SFC PPU OAM moved into PPU::Object; since nothing else uses it - the raw uint8[544] array is gone. OAM::read() constructs values from the OAM::Object[512] table now - this avoids having to determine how we want to sub-divide the two OAM memory sections - this also eliminates the OAM::synchronize() functionality - probably more I'm forgetting The FPS fluctuations are driving me insane. This WIP went from 128fps to 137fps. Settled on 133.5fps for the final build. But nothing I changed should have affected performance at all. This level of fluctuation makes it damn near impossible to know whether I'm speeding things up or slowing things down with changes.
353 lines
13 KiB
C++
353 lines
13 KiB
C++
#pragma once
|
|
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <algorithm>
|
|
#include <initializer_list>
|
|
#include <memory>
|
|
|
|
#include <nall/platform.hpp>
|
|
#include <nall/atoi.hpp>
|
|
#include <nall/function.hpp>
|
|
#include <nall/intrinsics.hpp>
|
|
#include <nall/memory.hpp>
|
|
#include <nall/primitives.hpp>
|
|
#include <nall/shared-pointer.hpp>
|
|
#include <nall/stdint.hpp>
|
|
#include <nall/utility.hpp>
|
|
#include <nall/varint.hpp>
|
|
#include <nall/vector.hpp>
|
|
|
|
namespace nall {
|
|
|
|
struct string;
|
|
struct string_view;
|
|
struct string_vector;
|
|
struct string_format;
|
|
|
|
//legacy naming convention
|
|
using lstring = string_vector;
|
|
|
|
struct string_view {
|
|
inline string_view();
|
|
inline string_view(const string_view& source);
|
|
inline string_view(string_view&& source);
|
|
inline string_view(const char* data);
|
|
inline string_view(const char* data, uint size);
|
|
inline string_view(const string& source);
|
|
template<typename... P> inline string_view(P&&... p);
|
|
inline ~string_view();
|
|
|
|
inline auto operator=(const string_view& source) -> string_view&;
|
|
inline auto operator=(string_view&& source) -> string_view&;
|
|
|
|
inline operator const char*() const;
|
|
inline auto data() const -> const char*;
|
|
inline auto size() const -> uint;
|
|
|
|
protected:
|
|
string* _string;
|
|
const char* _data;
|
|
mutable int _size;
|
|
};
|
|
|
|
#define NALL_STRING_ALLOCATOR_ADAPTIVE
|
|
//#define NALL_STRING_ALLOCATOR_COPY_ON_WRITE
|
|
//#define NALL_STRING_ALLOCATOR_SMALL_STRING_OPTIMIZATION
|
|
//#define NALL_STRING_ALLOCATOR_VECTOR
|
|
|
|
//cast.hpp
|
|
template<typename T> struct stringify;
|
|
|
|
//format.hpp
|
|
template<typename... P> inline auto print(P&&...) -> void;
|
|
template<typename... P> inline auto print(FILE*, P&&...) -> void;
|
|
template<typename T> inline auto numeral(T value, long precision = 0, char padchar = '0') -> string;
|
|
//inline auto integer(intmax_t value, long precision = 0, char padchar = '0') -> string;
|
|
//inline auto natural(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
|
inline auto hex(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
|
inline auto octal(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
|
inline auto binary(uintmax_t value, long precision = 0, char padchar = '0') -> string;
|
|
template<typename T> inline auto pointer(const T* value, long precision = 0) -> string;
|
|
inline auto pointer(uintptr_t value, long precision = 0) -> string;
|
|
//inline auto real(long double value) -> string;
|
|
|
|
//match.hpp
|
|
inline auto tokenize(const char* s, const char* p) -> bool;
|
|
inline auto tokenize(string_vector& list, const char* s, const char* p) -> bool;
|
|
|
|
//path.hpp
|
|
inline auto pathname(string_view self) -> string;
|
|
inline auto filename(string_view self) -> string;
|
|
|
|
inline auto dirname(string_view self) -> string;
|
|
inline auto basename(string_view self) -> string;
|
|
inline auto prefixname(string_view self) -> string;
|
|
inline auto suffixname(string_view self) -> string;
|
|
|
|
//utility.hpp
|
|
inline auto slice(string_view self, int offset = 0, int length = -1) -> string;
|
|
inline auto fromInteger(char* result, intmax_t value) -> char*;
|
|
inline auto fromNatural(char* result, uintmax_t value) -> char*;
|
|
inline auto fromReal(char* str, long double value) -> uint;
|
|
|
|
struct string {
|
|
using type = string;
|
|
|
|
protected:
|
|
#if defined(NALL_STRING_ALLOCATOR_ADAPTIVE)
|
|
enum : uint { SSO = 24 };
|
|
union {
|
|
struct { //copy-on-write
|
|
char* _data;
|
|
uint* _refs;
|
|
};
|
|
struct { //small-string-optimization
|
|
char _text[SSO];
|
|
};
|
|
};
|
|
inline auto _allocate() -> void;
|
|
inline auto _copy() -> void;
|
|
inline auto _resize() -> void;
|
|
#endif
|
|
|
|
#if defined(NALL_STRING_ALLOCATOR_COPY_ON_WRITE)
|
|
char* _data;
|
|
mutable uint* _refs;
|
|
inline auto _allocate() -> char*;
|
|
inline auto _copy() -> char*;
|
|
#endif
|
|
|
|
#if defined(NALL_STRING_ALLOCATOR_SMALL_STRING_OPTIMIZATION)
|
|
enum : uint { SSO = 24 };
|
|
union {
|
|
char* _data;
|
|
char _text[SSO];
|
|
};
|
|
#endif
|
|
|
|
#if defined(NALL_STRING_ALLOCATOR_VECTOR)
|
|
char* _data;
|
|
#endif
|
|
|
|
uint _capacity;
|
|
uint _size;
|
|
|
|
public:
|
|
inline string();
|
|
template<typename T = char> inline auto get() -> T*;
|
|
template<typename T = char> inline auto data() const -> const T*;
|
|
inline auto reset() -> type&;
|
|
inline auto reserve(uint) -> type&;
|
|
inline auto resize(uint) -> type&;
|
|
inline auto operator=(const string&) -> type&;
|
|
inline auto operator=(string&&) -> type&;
|
|
|
|
template<typename T, typename... P> string(T&& s, P&&... p) : string() {
|
|
append(forward<T>(s), forward<P>(p)...);
|
|
}
|
|
~string() { reset(); }
|
|
|
|
explicit operator bool() const { return _size; }
|
|
operator const char*() const { return (const char*)data(); }
|
|
|
|
auto size() const -> uint { return _size; }
|
|
auto capacity() const -> uint { return _capacity; }
|
|
|
|
auto operator==(const string& source) const -> bool {
|
|
return size() == source.size() && memory::compare(data(), source.data(), size()) == 0;
|
|
}
|
|
auto operator!=(const string& source) const -> bool {
|
|
return size() != source.size() || memory::compare(data(), source.data(), size()) != 0;
|
|
}
|
|
|
|
auto operator==(const char* source) const -> bool { return strcmp(data(), source) == 0; }
|
|
auto operator!=(const char* source) const -> bool { return strcmp(data(), source) != 0; }
|
|
|
|
auto operator==(string_view source) const -> bool { return compare(source) == 0; }
|
|
auto operator!=(string_view source) const -> bool { return compare(source) != 0; }
|
|
auto operator< (string_view source) const -> bool { return compare(source) < 0; }
|
|
auto operator<=(string_view source) const -> bool { return compare(source) <= 0; }
|
|
auto operator> (string_view source) const -> bool { return compare(source) > 0; }
|
|
auto operator>=(string_view source) const -> bool { return compare(source) >= 0; }
|
|
|
|
string(const string& source) : string() { operator=(source); }
|
|
string(string&& source) : string() { operator=(move(source)); }
|
|
|
|
auto begin() -> char* { return &get()[0]; }
|
|
auto end() -> char* { return &get()[size()]; }
|
|
auto begin() const -> const char* { return &data()[0]; }
|
|
auto end() const -> const char* { return &data()[size()]; }
|
|
|
|
//atoi.hpp
|
|
inline auto integer() const -> intmax_t;
|
|
inline auto natural() const -> uintmax_t;
|
|
inline auto hex() const -> uintmax_t;
|
|
inline auto real() const -> double;
|
|
|
|
//core.hpp
|
|
inline auto operator[](int) const -> const char&;
|
|
template<typename... P> inline auto assign(P&&...) -> type&;
|
|
template<typename T, typename... P> inline auto append(const T&, P&&...) -> type&;
|
|
template<typename... P> inline auto append(const nall::string_format&, P&&...) -> type&;
|
|
inline auto append() -> type&;
|
|
template<typename T> inline auto _append(const stringify<T>&) -> string&;
|
|
inline auto length() const -> uint;
|
|
|
|
//datetime.hpp
|
|
inline static auto date(time_t = 0) -> string;
|
|
inline static auto time(time_t = 0) -> string;
|
|
inline static auto datetime(time_t = 0) -> string;
|
|
|
|
//find.hpp
|
|
template<bool, bool> inline auto _find(int, string_view) const -> maybe<uint>;
|
|
|
|
inline auto find(string_view source) const -> maybe<uint>;
|
|
inline auto ifind(string_view source) const -> maybe<uint>;
|
|
inline auto qfind(string_view source) const -> maybe<uint>;
|
|
inline auto iqfind(string_view source) const -> maybe<uint>;
|
|
|
|
inline auto findFrom(int offset, string_view source) const -> maybe<uint>;
|
|
inline auto ifindFrom(int offset, string_view source) const -> maybe<uint>;
|
|
|
|
//format.hpp
|
|
inline auto format(const nall::string_format& params) -> type&;
|
|
|
|
//compare.hpp
|
|
template<bool> inline static auto _compare(const char*, uint, const char*, uint) -> int;
|
|
|
|
inline static auto compare(string_view, string_view) -> int;
|
|
inline static auto icompare(string_view, string_view) -> int;
|
|
|
|
inline auto compare(string_view source) const -> int;
|
|
inline auto icompare(string_view source) const -> int;
|
|
|
|
inline auto equals(string_view source) const -> bool;
|
|
inline auto iequals(string_view source) const -> bool;
|
|
|
|
inline auto beginsWith(string_view source) const -> bool;
|
|
inline auto ibeginsWith(string_view source) const -> bool;
|
|
|
|
inline auto endsWith(string_view source) const -> bool;
|
|
inline auto iendsWith(string_view source) const -> bool;
|
|
|
|
//convert.hpp
|
|
inline auto downcase() -> type&;
|
|
inline auto upcase() -> type&;
|
|
|
|
inline auto qdowncase() -> type&;
|
|
inline auto qupcase() -> type&;
|
|
|
|
inline auto transform(string_view from, string_view to) -> type&;
|
|
|
|
//match.hpp
|
|
inline auto match(string_view source) const -> bool;
|
|
inline auto imatch(string_view source) const -> bool;
|
|
|
|
//replace.hpp
|
|
template<bool, bool> inline auto _replace(string_view, string_view, long) -> type&;
|
|
inline auto replace(string_view from, string_view to, long limit = LONG_MAX) -> type&;
|
|
inline auto ireplace(string_view from, string_view to, long limit = LONG_MAX) -> type&;
|
|
inline auto qreplace(string_view from, string_view to, long limit = LONG_MAX) -> type&;
|
|
inline auto iqreplace(string_view from, string_view to, long limit = LONG_MAX) -> type&;
|
|
|
|
//split.hpp
|
|
inline auto split(string_view key, long limit = LONG_MAX) const -> string_vector;
|
|
inline auto isplit(string_view key, long limit = LONG_MAX) const -> string_vector;
|
|
inline auto qsplit(string_view key, long limit = LONG_MAX) const -> string_vector;
|
|
inline auto iqsplit(string_view key, long limit = LONG_MAX) const -> string_vector;
|
|
|
|
//trim.hpp
|
|
inline auto trim(string_view lhs, string_view rhs, long limit = LONG_MAX) -> type&;
|
|
inline auto trimLeft(string_view lhs, long limit = LONG_MAX) -> type&;
|
|
inline auto trimRight(string_view rhs, long limit = LONG_MAX) -> type&;
|
|
|
|
inline auto itrim(string_view lhs, string_view rhs, long limit = LONG_MAX) -> type&;
|
|
inline auto itrimLeft(string_view lhs, long limit = LONG_MAX) -> type&;
|
|
inline auto itrimRight(string_view rhs, long limit = LONG_MAX) -> type&;
|
|
|
|
inline auto strip() -> type&;
|
|
inline auto stripLeft() -> type&;
|
|
inline auto stripRight() -> type&;
|
|
|
|
//utility.hpp
|
|
inline static auto read(string_view filename) -> string;
|
|
inline static auto repeat(string_view pattern, uint times) -> string;
|
|
inline auto fill(char fill = ' ') -> type&;
|
|
inline auto hash() const -> uint;
|
|
inline auto remove(uint offset, uint length) -> type&;
|
|
inline auto reverse() -> type&;
|
|
inline auto size(int length, char fill = ' ') -> type&;
|
|
};
|
|
|
|
struct string_vector : vector<string> {
|
|
using type = string_vector;
|
|
|
|
string_vector(const string_vector& source) { vector::operator=(source); }
|
|
string_vector(string_vector& source) { vector::operator=(source); }
|
|
string_vector(string_vector&& source) { vector::operator=(move(source)); }
|
|
template<typename... P> string_vector(P&&... p) { append(forward<P>(p)...); }
|
|
|
|
//list.hpp
|
|
inline auto operator==(const string_vector&) const -> bool;
|
|
inline auto operator!=(const string_vector&) const -> bool;
|
|
|
|
inline auto operator=(const string_vector& source) -> type& { return vector::operator=(source), *this; }
|
|
inline auto operator=(string_vector& source) -> type& { return vector::operator=(source), *this; }
|
|
inline auto operator=(string_vector&& source) -> type& { return vector::operator=(move(source)), *this; }
|
|
|
|
inline auto isort() -> type&;
|
|
|
|
template<typename... P> inline auto append(const string&, P&&...) -> type&;
|
|
inline auto append() -> type&;
|
|
|
|
inline auto find(string_view source) const -> maybe<uint>;
|
|
inline auto ifind(string_view source) const -> maybe<uint>;
|
|
inline auto match(string_view pattern) const -> string_vector;
|
|
inline auto merge(string_view separator) const -> string;
|
|
inline auto strip() -> type&;
|
|
|
|
//split.hpp
|
|
template<bool, bool> inline auto _split(string_view, string_view, long) -> type&;
|
|
};
|
|
|
|
struct string_format : vector<string> {
|
|
using type = string_format;
|
|
|
|
template<typename... P> string_format(P&&... p) { reserve(sizeof...(p)); append(forward<P>(p)...); }
|
|
template<typename T, typename... P> inline auto append(const T&, P&&... p) -> type&;
|
|
inline auto append() -> type&;
|
|
};
|
|
|
|
}
|
|
|
|
#include <nall/string/view.hpp>
|
|
#include <nall/string/atoi.hpp>
|
|
#include <nall/string/cast.hpp>
|
|
#include <nall/string/compare.hpp>
|
|
#include <nall/string/convert.hpp>
|
|
#include <nall/string/core.hpp>
|
|
#include <nall/string/datetime.hpp>
|
|
#include <nall/string/find.hpp>
|
|
#include <nall/string/format.hpp>
|
|
#include <nall/string/list.hpp>
|
|
#include <nall/string/match.hpp>
|
|
#include <nall/string/path.hpp>
|
|
#include <nall/string/replace.hpp>
|
|
#include <nall/string/split.hpp>
|
|
#include <nall/string/trim.hpp>
|
|
#include <nall/string/utility.hpp>
|
|
#include <nall/string/eval/node.hpp>
|
|
#include <nall/string/eval/literal.hpp>
|
|
#include <nall/string/eval/parser.hpp>
|
|
#include <nall/string/eval/evaluator.hpp>
|
|
#include <nall/string/markup/node.hpp>
|
|
#include <nall/string/markup/find.hpp>
|
|
#include <nall/string/markup/bml.hpp>
|
|
#include <nall/string/markup/xml.hpp>
|
|
#include <nall/string/transform/cml.hpp>
|
|
#include <nall/string/transform/dml.hpp>
|