X-Git-Url: https://git.ucc.asn.au/?p=tpg%2Facess2.git;a=blobdiff_plain;f=Usermode%2FLibraries%2Flibc%2B%2B.so_src%2Finclude_exp%2Fstring;fp=Usermode%2FLibraries%2Flibc%2B%2B.so_src%2Finclude_exp%2Fstring;h=f36077dda2c1b5e07248ef6d0e8e85418b9bdf32;hp=0000000000000000000000000000000000000000;hb=845b6f9d90bb87b5e760e4d49aa93b0e003ab750;hpb=67a7fe2bb79eceaf10c572a99bd8345c4e81cf5b diff --git a/Usermode/Libraries/libc++.so_src/include_exp/string b/Usermode/Libraries/libc++.so_src/include_exp/string new file mode 100644 index 00000000..f36077dd --- /dev/null +++ b/Usermode/Libraries/libc++.so_src/include_exp/string @@ -0,0 +1,604 @@ +/* + * Acess2 C++ Library + * - By John Hodge (thePowersGang) + * + * string (header) + * - C++'s String type + */ +#ifndef _LIBCXX_STRING_ +#define _LIBCXX_STRING_ + +#include "_libcxx_helpers.h" +#include +#include + +namespace std { + +template +struct char_traits +{ +}; + +template <> +struct char_traits +{ + typedef char char_type; + typedef int int_type; + //typedef streamoff off_type; + //typedef streampos pos_type; + //typedef mbstate_t state_type; + + static bool eq(const char_type& c, const char_type& d) { + return c == d; + } + static bool lt(const char_type& c, const char_type& d) { + return c < d; + } + static size_t length(const char_type* s) { + size_t ret = 0; + while(*s++) ret ++; + return ret; + } + static int compare (const char_type* p, const char_type* q, size_t n) { + while (n--) { + if( !eq(*p,*q) ) + return lt(*p,*q) ? -1 : 1; + ++p; ++q; + } + return 0; + } +}; + +template <> +struct char_traits +{ + typedef wchar_t char_type; + typedef int int_type; + //typedef streamoff off_type; + //typedef streampos pos_type; + //typedef mbstate_t state_type; + + static size_t length(const char_type* s) { + size_t ret = 0; + while(*s++) ret ++; + return ret; + } + static bool eq(const char_type& c, const char_type& d) { + return c == d; + } + static bool lt(const char_type& c, const char_type& d) { + return c < d; + } +}; + +extern void _throw_out_of_range(const char *message); + +template < class charT, class traits=char_traits, class Alloc=allocator > +class basic_string +{ +public: + typedef traits traits_type; + typedef Alloc allocator_type; + typedef charT value_type; + typedef typename allocator_type::reference reference; + typedef typename allocator_type::const_reference const_reference; + typedef size_t size_type; + + typedef charT* iterator; + typedef const charT* const_iterator; + +private: + struct dynamic_info + { + allocator_type m_allocator; + int m_ref_count = 1; + size_type m_capacity = 0; + size_type m_size = 0; + typename allocator_type::pointer m_data = 0; + dynamic_info(const allocator_type& alloc): + m_allocator(alloc) + { + } + dynamic_info(const dynamic_info& other): + m_allocator(other.m_allocator), + m_ref_count(1), + m_capacity(other.m_capacity), + m_size(other.m_size) + { + m_data = m_allocator.allocate(m_capacity); + for( size_type i = 0; i < m_size; i ++ ) + m_data[i] = other.m_data[i]; + } + }; + + allocator_type m_allocator; + dynamic_info *m_content; + +public: + basic_string(const allocator_type& alloc = allocator_type()): + m_allocator(alloc), + m_content(0) + { + } + basic_string(const basic_string& str) throw(): + basic_string(allocator_type()) + { + *this = str; + } + #if _CXX11_AVAIL + basic_string(basic_string&& str): + m_allocator(str.m_allocator), + m_content(str.m_content) + { + str.m_content = 0; + ::_sys::debug("basic_string(move) %p %s", m_content, c_str()); + } + #endif + basic_string(const basic_string& str, const allocator_type& alloc): + basic_string(str, 0, str.length(), alloc) + { + } + basic_string(const basic_string& str, size_type pos, size_type len = npos, const allocator_type& alloc = allocator_type()): + basic_string(alloc) + { + if( pos < str.length() ) + { + if( len > str.length() - pos ) + len = str.length() - pos; + reserve(len); + for( size_type i = 0; i < len; i ++ ) + m_content->m_data[i] = str.m_content->m_data[pos+i]; + m_content->m_size = len; + } + } + basic_string(const charT *s, const allocator_type& alloc = allocator_type()): + basic_string(s, traits::length(s), alloc) + { + } + basic_string(const charT *s, size_type n, const allocator_type& alloc = allocator_type()): + basic_string(alloc) + { + if( n > 0 ) + { + reserve(n); + for( size_type i = 0; i < n; i ++ ) + m_content->m_data[i] = s[i]; + m_content->m_data[n] = 0; + m_content->m_size = n; + } + } + basic_string(size_type n, charT c, const allocator_type& alloc = allocator_type()): + basic_string(alloc) + { + if( n > 0 ) + { + reserve(n); + for( size_type i = 0; i < n; i ++ ) + m_content->m_data[i] = c; + m_content->m_data[n] = 0; + m_content->m_size = n; + } + } + #if __cplusplus < 199711L + basic_string(basic_string&& str) noexcept: + basic_string(allocator_type()) + { + } + basic_string(basic_string&& str, const allocator_type& alloc) noexcept: + basic_string(alloc) + { + m_content = str.m_content; + str.m_content = 0; + } + #endif + ~basic_string() + { + release_content(); + } + basic_string& operator=(const basic_string& str) throw() { + return assign(str); + } + basic_string& operator=(const charT* s) { + return assign(s); + } + basic_string& operator=(charT c) { + return assign(c); + } + + // iterators + + // capacity + size_type size() const { + return m_content ? m_content->m_size : 0; + } + size_type length() const { + return size(); + } + size_type max_size() const { + return -1; + } + void resize(size_type size, charT c = 0) { + reserve(size); + if( m_content->m_size < size ) { + for( size_type ofs = m_content->m_size; ofs < size; ofs ++ ) + m_content->m_data[ofs] = c; + m_content->m_data[size] = 0; + } + m_content->m_size = size; + m_content->m_data[size] = 0; + } + size_type capacity() const { + return m_content ? m_content->m_capacity : 0; + } + void reserve(size_type size) { + own_content(); + size = (size+1 + 31) & ~31; + if( size > m_content->m_capacity ) { + auto new_area = m_allocator.allocate(size); + for( size_type i = 0; i < m_content->m_size; i ++ ) + new_area[i] = m_content->m_data[i]; + m_allocator.deallocate(m_content->m_data, m_content->m_capacity); + m_content->m_data = new_area; + m_content->m_capacity = size; + } + } + void clear() { + own_content(); + m_content->m_size = 0; + } + bool empty() const { + return length() == 0; + } + #if _CXX11_AVAIL + void shrink_to_fit(); + #endif + + // Access + reference operator[] (size_type pos) { + own_content(); + return m_content->m_data[pos]; + } + const_reference operator[] (size_type pos) const { + return (m_content ? m_content->m_data[pos] : *(const charT*)0); + } + reference at(size_type pos) { + own_content(); + if(pos >= m_content->m_size) + _throw_out_of_range("basic_string - at"); + return m_content->m_data[pos]; + } + const_reference at(size_type pos) const { + if(!m_content || pos >= m_content.m_size) + _throw_out_of_range("basic_string - at"); + return m_content->m_data[pos]; + } + #if _CXX11_AVAIL + reference back() { + own_content(); + return m_content->m_data[m_content->m_size]; + } + const_reference back() const { + return m_content->m_data[m_content->m_size]; + } + reference front() { + own_content(); + return m_content->m_data[0]; + } + const_reference front() const { + return m_content->m_data[0]; + } + #endif + + // Modifiers + basic_string& operator +=(const basic_string& str) { + return append(str); + } + basic_string& operator +=(const charT* s) { + return append(s); + } + basic_string& operator +=(charT c) { + push_back(c); + return *this; + } + basic_string& append(const basic_string& str) { + return append(str, 0, npos); + } + basic_string& append(const basic_string& str, size_type subpos, size_type sublen) { + if(subpos >= str.size()) + _throw_out_of_range("basic_string - assign source"); + if( sublen > str.size() - subpos ) + sublen = str.size() - subpos; + append( str.data() + subpos, sublen ); + return *this; + } + basic_string& append(const charT* s) { + return append(s, traits::length(s)); + } + basic_string& append(const charT* s, size_type n) { + reserve(size() + n); + for( size_type i = 0; i < n; i ++ ) + m_content->m_data[size() + i] = s[i]; + m_content->m_data[size()+n] = '\0'; + m_content->m_size += n; + return *this; + } + basic_string& append(size_type n, charT c) { + reserve(size() + n); + for( size_type i = 0; i < n; i ++ ) + m_content->m_data[size() + i] = c; + m_content->m_data[size()+n] = '\0'; + m_content->m_size += n; + return *this; + } + void push_back(charT c) { + append(1, c); + } + basic_string& assign(const basic_string& str) throw() { + // Special case, triggers copy-on-write. + release_content(); + m_content = str.m_content; + m_content->m_ref_count ++; + return *this; + } + basic_string& assign(const basic_string& str, size_type subpos, size_type sublen) { + if(subpos >= str.size()) + _throw_out_of_range("basic_string - assign source"); + if( sublen > str.size() - subpos ) + sublen = str.size() - subpos; + + return assign(str.data() + subpos, sublen); + } + basic_string& assign(const charT* s) { + return assign(s, traits::length(s)); + } + basic_string& assign(const charT* s, size_type n) { + release_content(); + reserve(n); + for( size_type i = 0; i < n; i ++ ) + m_content->m_data[i] = s[i]; + m_content->m_data[n] = '\0'; + m_content->m_size = n; + return *this; + } + basic_string& assign(size_type n, charT c) { + release_content(); + reserve(n); + for( size_type i = 0; i < n; i ++ ) + m_content->m_data[i] = c; + m_content->m_data[n] = '\0'; + m_content->m_size = n; + return *this; + } + + basic_string& insert(size_type pos, const basic_string& str); + basic_string& insert(size_type pos, const basic_string& str, size_type subpos, size_type sublen); + basic_string& insert(size_type pos, const charT& s); + basic_string& insert(size_type pos, const charT& s, size_type n); + basic_string& insert(size_type pos, size_type n, charT c); + iterator insert(const_iterator p, size_type n, charT c); + iterator insert(const_iterator p, charT c); + template + iterator insert(iterator p, InputIterator first, InputIterator last); + #if _CXX11_AVAIL + basic_string& insert(const_iterator p, initializer_list il); + #endif + + basic_string& erase(size_type pos = 0, size_type len = npos); + iterator erase(const_iterator p); + iterator erase(const_iterator first, const_iterator last); + + basic_string& replace(size_type pos, size_type len, const basic_string& str); + basic_string& replace(const_iterator i1, const_reference i2, const basic_string& str); + basic_string& replace(size_type pos, size_type len, const basic_string& str, size_type subpos, size_type sublen); + basic_string& replace(size_type pos, size_type len, const charT *s); + basic_string& replace(const_iterator i1, const_reference i2, const charT* s); + basic_string& replace(size_type pos, size_type len, const charT *s, size_type n); + basic_string& replace(const_iterator i1, const_reference i2, const charT* s, size_type n); + basic_string& replace(size_type pos, size_type len, size_type n, charT c); + basic_string& replace(const_iterator i1, const_reference i2, size_type n, charT c); + template + basic_string& replace(const_iterator i1, const_reference i2, InputIterator first, InputIterator last); + basic_string& replace(const_iterator i1, const_iterator i2, initializer_list il); + + void swap(basic_string& str) + { + auto tmp = m_content; + m_content = str.m_content; + str.m_content = tmp; + } + + #if _CXX11_AVAIL + void pop_back(); + #endif + + // String operations + const charT *c_str() const noexcept + { + // TODO: this is const, but also might need to do processing + if(m_content) { + _libcxx_assert(m_content->m_data[m_content->m_size] == '\0'); + } + return (m_content ? m_content->m_data : ""); + } + const charT *data() const + { + return (m_content ? m_content->m_data : NULL); + } + allocator_type get_allocator() const noexcept + { + return m_allocator; + } + size_type copy(charT* s, size_type len, size_type pos = 0) const; + + size_type find(const basic_string& str, size_type pos = 0) const noexcept; + size_type find(const charT* s, size_type pos = 0) const; + size_type find(const charT* s, size_type pos, size_type n) const; + size_type find(charT c, size_type pos = 0) const noexcept; + + size_type rfind(const basic_string& str, size_type pos = 0) const noexcept; + size_type rfind(const charT* s, size_type pos = 0) const; + size_type rfind(const charT* s, size_type pos, size_type n) const; + size_type rfind(charT c, size_type pos = 0) const noexcept; + + size_type find_first_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_of(const charT* s, size_type pos = 0) const; + size_type find_first_of(const charT* s, size_type pos, size_type n) const; + size_type find_first_of(charT c, size_type pos = 0) const noexcept; + + size_type find_last_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_last_of(const charT* s, size_type pos = 0) const; + size_type find_last_of(const charT* s, size_type pos, size_type n) const; + size_type find_last_of(charT c, size_type pos = 0) const noexcept; + + size_type find_first_not_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_first_not_of(const charT* s, size_type pos = 0) const; + size_type find_first_not_of(const charT* s, size_type pos, size_type n) const; + size_type find_first_not_of(charT c, size_type pos = 0) const noexcept; + + size_type find_last_not_of(const basic_string& str, size_type pos = 0) const noexcept; + size_type find_last_not_of(const charT* s, size_type pos = 0) const; + size_type find_last_not_of(const charT* s, size_type pos, size_type n) const; + size_type find_last_not_of(charT c, size_type pos = 0) const noexcept; + + basic_string substr(size_type pos = 0, size_type len = npos) const; + + int compare(const basic_string& str) const noexcept { + return compare(0, size(), str.data(), str.size()); + } + int compare(size_type pos, size_type len, const basic_string& str) const { + _libcxx_assert(pos <= size()); + _libcxx_assert(len <= size()); + _libcxx_assert(pos+len <= size()); + return compare(pos, len, str.data(), str.size()); + } + int compare(size_type pos, size_type len, const basic_string& str, size_type subpos, size_type sublen) const { + // TODO: check + _libcxx_assert(subpos <= str.size()); + _libcxx_assert(sublen <= str.size()); + _libcxx_assert(subpos+sublen <= str.size()); + return compare(pos, len, str.data()+subpos, sublen); + } + int compare(const charT* s) const { + return compare(0, npos, s, traits::length(s)); + } + int compare(size_type pos, size_type len, const charT* s) const { + return compare(pos, len, s, traits::length(s)); + } + int compare(size_type pos, size_type len, const charT* s, size_type n) const { + if( n <= len ) { + int rv = traits::compare(data()+pos, s, n); + if( rv == 0 && n < len ) { + rv = -1; + } + return rv; + } + else { + int rv = traits::compare(data()+pos, s, len); + if(rv == 0) { + rv = 1; + } + return rv; + } + } + + static const size_type npos = -1; +private: + void own_content() { + if(!m_content) + { + m_content = new dynamic_info(m_allocator); + } + else if( m_content->m_ref_count > 1 ) + { + dynamic_info *new_cont = new dynamic_info(*m_content); + m_content->m_ref_count --; + m_content = new_cont; + } + else + { + // already owned + } + } + void release_content() { + if( m_content ) + { + m_content->m_ref_count --; + if( m_content->m_ref_count == 0 ) { + m_allocator.deallocate(m_content->m_data, m_content->m_capacity); + delete m_content; + } + m_content = NULL; + } + } +}; + +typedef basic_string string; + +#define _libcxx_str basic_string + +template +basic_string operator+(const basic_string& lhs, const basic_string& rhs) +{ + basic_string ret; + ret.reserve(lhs.size() + rhs.size()); + ret += lhs; + ret += rhs; + return ret; +} +template +basic_string operator+(const basic_string& lhs, const charT* rhs) +{ + basic_string ret; + ret.reserve(lhs.size() + traits::length(rhs)); + ret += lhs; + ret += rhs; + return ret; +} +template +basic_string operator+(const charT* lhs, const basic_string& rhs) +{ + basic_string ret; + ret.reserve(traits::length(lhs) + rhs.size()); + ret += lhs; + ret += rhs; + return ret; +} +template +basic_string operator+(const basic_string& lhs, const charT rhs) +{ + basic_string ret; + ret.reserve(lhs.size() + 1); + ret += lhs; + ret += rhs; + return ret; +} +template +basic_string operator+(const charT lhs, const basic_string& rhs) +{ + basic_string ret; + ret.reserve(1 + rhs.size()); + ret += lhs; + ret += rhs; + return ret; +} + +// Three overloads each +// name: Actual operator, opp: reversed operator +#define _libcxx_string_def_cmp(name, opp) \ + template \ + bool operator name(const _libcxx_str& lhs, const _libcxx_str& rhs) { return lhs.compare(rhs) name 0; } \ + template \ + bool operator name(const charT* lhs, const _libcxx_str& rhs) { return rhs.compare(lhs) opp 0; } \ + template \ + bool operator name(const _libcxx_str& lhs, const charT* rhs) { return lhs.compare(rhs) name 0; } + +_libcxx_string_def_cmp(<, >) +_libcxx_string_def_cmp(<=, >=) +_libcxx_string_def_cmp(==, ==) +_libcxx_string_def_cmp(>=, <=) +_libcxx_string_def_cmp(>, <) +}; + +#endif + +// vim: ft=cpp