mirror of
https://github.com/bsnes-emu/bsnes.git
synced 2025-10-04 23:31:44 +02:00
byuu says: Changelog: - entire GBA core ported to auto function() -> return; syntax - fixed GBA BLDY bug that was causing flickering in a few games - replaced nall/config usage with nall/string/markup/node - this merges all configuration files to a unified settings.bml file - added "Ignore Manifests" option to the advanced setting tab - this lets you keep a manifest.bml for an older version of higan; if you want to do regression testing Be sure to remap your controller/hotkey inputs, and for SNES, choose "Gamepad" from "Controller Port 1" in the system menu. Otherwise you won't get any input. No need to blow away your old config files, unless you want to.
124 lines
2.8 KiB
C++
124 lines
2.8 KiB
C++
#ifdef NALL_STRING_INTERNAL_HPP
|
|
|
|
/*****
|
|
adaptive allocator
|
|
sizeof(string) == SSO + 8
|
|
|
|
aggressively tries to avoid heap allocations
|
|
small strings are stored on the stack
|
|
large strings are shared via copy-on-write
|
|
|
|
SSO alone is very slow on large strings due to copying
|
|
SSO alone is very slightly faster than this allocator on small strings
|
|
|
|
COW alone is very slow on small strings due to heap allocations
|
|
COW alone is very slightly faster than this allocator on large strings
|
|
|
|
adaptive is thus very fast for all string sizes
|
|
*****/
|
|
|
|
namespace nall {
|
|
|
|
string::string() : _data(nullptr), _capacity(SSO - 1), _size(0) {
|
|
}
|
|
|
|
auto string::get() -> char* {
|
|
if(_capacity < SSO) return _text;
|
|
if(*_refs > 1) _copy();
|
|
return _data;
|
|
}
|
|
|
|
auto string::data() const -> const char* {
|
|
if(_capacity < SSO) return _text;
|
|
return _data;
|
|
}
|
|
|
|
auto string::reset() -> type& {
|
|
if(_capacity >= SSO && !--*_refs) memory::free(_data);
|
|
_data = nullptr;
|
|
_capacity = SSO - 1;
|
|
_size = 0;
|
|
return *this;
|
|
}
|
|
|
|
auto string::reserve(uint capacity) -> type& {
|
|
if(capacity <= _capacity) return *this;
|
|
capacity = bit::round(capacity + 1) - 1;
|
|
if(_capacity < SSO) {
|
|
_capacity = capacity;
|
|
_allocate();
|
|
} else if(*_refs > 1) {
|
|
_capacity = capacity;
|
|
_copy();
|
|
} else {
|
|
_capacity = capacity;
|
|
_resize();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
auto string::resize(uint size) -> type& {
|
|
reserve(size);
|
|
get()[_size = size] = 0;
|
|
return *this;
|
|
}
|
|
|
|
auto string::operator=(const string& source) -> type& {
|
|
if(&source == this) return *this;
|
|
reset();
|
|
if(source._capacity >= SSO) {
|
|
_data = source._data;
|
|
_refs = source._refs;
|
|
_capacity = source._capacity;
|
|
_size = source._size;
|
|
++*_refs;
|
|
} else {
|
|
memory::copy(_text, source._text, SSO);
|
|
_capacity = source._capacity;
|
|
_size = source._size;
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
auto string::operator=(string&& source) -> type& {
|
|
if(&source == this) return *this;
|
|
reset();
|
|
memory::copy(this, &source, sizeof(string));
|
|
source._data = nullptr;
|
|
source._capacity = SSO - 1;
|
|
source._size = 0;
|
|
return *this;
|
|
}
|
|
|
|
//SSO -> COW
|
|
auto string::_allocate() -> void {
|
|
char _temp[SSO];
|
|
memory::copy(_temp, _text, SSO);
|
|
_data = (char*)memory::allocate(_capacity + 1 + sizeof(uint));
|
|
memory::copy(_data, _temp, SSO);
|
|
_refs = (uint*)(_data + _capacity + 1); //always aligned by 32 via reserve()
|
|
*_refs = 1;
|
|
}
|
|
|
|
//COW -> Unique
|
|
auto string::_copy() -> void {
|
|
auto _temp = (char*)memory::allocate(_capacity + 1 + sizeof(uint));
|
|
memory::copy(_temp, _data, _size = min(_capacity, _size));
|
|
_temp[_size] = 0;
|
|
--*_refs;
|
|
_data = _temp;
|
|
_refs = (uint*)(_data + _capacity + 1);
|
|
*_refs = 1;
|
|
}
|
|
|
|
//COW -> Resize
|
|
auto string::_resize() -> void {
|
|
_data = (char*)memory::resize(_data, _capacity + 1 + sizeof(uint));
|
|
_refs = (uint*)(_data + _capacity + 1);
|
|
*_refs = 1;
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|