Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace nall {
- string::string() : _data(nullptr), _capacity(SSO - 1), _size(0) {
- }
- auto string::pointer() -> 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(unsigned 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(unsigned size) -> type& {
- reserve(size);
- pointer()[_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(unsigned));
- memory::copy(_data, _temp, SSO);
- _refs = (unsigned*)(_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(unsigned));
- memory::copy(_temp, _data, _size = min(_capacity, _size));
- _temp[_size] = 0;
- --*_refs;
- _data = _temp;
- _refs = (unsigned*)(_data + _capacity + 1);
- *_refs = 1;
- }
- //COW -> Resize
- auto string::_resize() -> void {
- _data = (char*)memory::resize(_data, _capacity + 1 + sizeof(unsigned));
- _refs = (unsigned*)(_data + _capacity + 1);
- *_refs = 1;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement