From ac36ea057c987a14f50409f92fc5a31720d8b604 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Sat, 24 May 2014 23:11:10 +0800 Subject: [PATCH] Usermode/libc++ - system_error and vector implementation --- Usermode/Libraries/libc++.so_src/Makefile | 2 +- .../libc++.so_src/include_exp/cerrno | 6 + .../libc++.so_src/include_exp/cstdio | 6 + .../Libraries/libc++.so_src/include_exp/list | 2 + .../libc++.so_src/include_exp/string | 107 +++++++++- .../libc++.so_src/include_exp/system_error | 186 ++++++++++++++++++ .../libc++.so_src/include_exp/vector | 178 ++++++++++++++++- .../Libraries/libc++.so_src/system_error.cc | 106 ++++++++++ 8 files changed, 582 insertions(+), 11 deletions(-) create mode 100644 Usermode/Libraries/libc++.so_src/include_exp/cerrno create mode 100644 Usermode/Libraries/libc++.so_src/include_exp/cstdio create mode 100644 Usermode/Libraries/libc++.so_src/include_exp/system_error create mode 100644 Usermode/Libraries/libc++.so_src/system_error.cc diff --git a/Usermode/Libraries/libc++.so_src/Makefile b/Usermode/Libraries/libc++.so_src/Makefile index 0e62c53a..c76ac434 100644 --- a/Usermode/Libraries/libc++.so_src/Makefile +++ b/Usermode/Libraries/libc++.so_src/Makefile @@ -11,7 +11,7 @@ LDFLAGS += -Map map.txt -lc OBJ = misc.o new.o guard.o cxxabi.o typeinfo.o OBJ += string.o -OBJ += exceptions.o exception_handling.o +OBJ += exceptions.o exception_handling.o system_error.o DEPFILES := $(OBJ:%.o=%.d) BIN = libc++.so ifeq ($(ARCHDIR),native) diff --git a/Usermode/Libraries/libc++.so_src/include_exp/cerrno b/Usermode/Libraries/libc++.so_src/include_exp/cerrno new file mode 100644 index 00000000..3ebd48a3 --- /dev/null +++ b/Usermode/Libraries/libc++.so_src/include_exp/cerrno @@ -0,0 +1,6 @@ +/* + */ +extern "C" { +#include +} +// vim: ft=cpp diff --git a/Usermode/Libraries/libc++.so_src/include_exp/cstdio b/Usermode/Libraries/libc++.so_src/include_exp/cstdio new file mode 100644 index 00000000..f41fd058 --- /dev/null +++ b/Usermode/Libraries/libc++.so_src/include_exp/cstdio @@ -0,0 +1,6 @@ +/* + */ +extern "C" { +#include +} +// vim: ft=cpp diff --git a/Usermode/Libraries/libc++.so_src/include_exp/list b/Usermode/Libraries/libc++.so_src/include_exp/list index 060e4e31..ff826141 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/list +++ b/Usermode/Libraries/libc++.so_src/include_exp/list @@ -203,9 +203,11 @@ public: } list_iterator& operator ++ () { cur = cur->next; + return *this; } list_iterator& operator -- () { cur = cur->prev; + return *this; } private: diff --git a/Usermode/Libraries/libc++.so_src/include_exp/string b/Usermode/Libraries/libc++.so_src/include_exp/string index 84c3ef33..ac9e5f37 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/string +++ b/Usermode/Libraries/libc++.so_src/include_exp/string @@ -256,13 +256,36 @@ public: 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); + 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); - basic_string& append(size_type n, charT c); - void push_back(charT c); + 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(); @@ -270,7 +293,35 @@ public: m_content->m_ref_count ++; return *this; } - basic_string& assign(const basic_string& str, size_type subpos, size_type sublen); + 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; + } // String operations const char *c_str() const { @@ -317,6 +368,52 @@ private: typedef basic_string 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; +} + }; #endif diff --git a/Usermode/Libraries/libc++.so_src/include_exp/system_error b/Usermode/Libraries/libc++.so_src/include_exp/system_error new file mode 100644 index 00000000..ec08bee1 --- /dev/null +++ b/Usermode/Libraries/libc++.so_src/include_exp/system_error @@ -0,0 +1,186 @@ +/* + * Acess2 C++ Library + * - By John Hodge (thePowersGang) + * + * system_error (header) + * - C++11's system_error exception + */ +#ifndef _LIBCXX_SYSTEM_ERROR_ +#define _LIBCXX_SYSTEM_ERROR_ + +#if __cplusplus <= 199711L // C++11 check +# error "This header requires C++11 support enabled" +#endif + +#include + +namespace std { + +class error_category; +class error_condition; +class error_code; + +bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept; +bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept; +bool operator< (const error_condition& lhs, const error_condition& rhs) noexcept; +bool operator==(const error_condition& lhs, const error_code& rhs) noexcept; +bool operator==(const error_code& lhs, const error_condition& rhs) noexcept; +bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept; +bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept; + +extern const error_category& generic_category() noexcept; +extern const error_category& system_category() noexcept; + +class error_condition +{ + int m_val; + const error_category* m_cat; +public: + error_condition() noexcept: + error_condition(0, ::std::generic_category()) + { + } + error_condition(int val, const error_category& cat) noexcept: + m_val(val), + m_cat(&cat) + { + } + //template error_condition(ErrorConditionEnum e) noexcept; + //template error_condition& operator=(ErrorConditionEnum e) noexcept; + void assign(int val, const error_category& cat) noexcept { + m_val = val; + m_cat = &cat; + } + void clear() noexcept { + assign(0, ::std::generic_category()); + } + int value() const noexcept { + return m_val; + } + const error_category& category() const noexcept { + return *m_cat; + } + string message() const; + explicit operator bool() const noexcept { + return m_val != 0; + } +}; + +class error_category +{ +public: + error_category() { + } + error_category(const error_category&) = delete; // disallow copying + virtual ~error_category() noexcept { + } + bool operator==(const error_category& rhs) const noexcept { + return this == &rhs; + } + bool operator!=(const error_category& rhs) const noexcept { + return !(*this == rhs); + } + bool operator<(const error_category& rhs) const noexcept { + return this < &rhs; + } + virtual const char* name() const noexcept = 0; + virtual error_condition default_error_condition(int val) const noexcept { + return error_condition(val, *this); + } + virtual bool equivalent(int valcode, const ::std::error_condition& cond) const noexcept { + return default_error_condition(valcode) == cond; + } + virtual bool equivalent(const error_code& code, int valcond) const noexcept; // in system_error.cc + virtual ::std::string message(int val) const = 0; +}; + +class error_code +{ + int m_ev; + const ::std::error_category* m_ecat; +public: + error_code() noexcept: + error_code(0, ::std::generic_category()) + { + } + error_code(int ev, const ::std::error_category& ecat) noexcept: + m_ev(ev), + m_ecat(&ecat) + { + } + //template + //error_code(ErrorCodeEnum e) noexcept; + void assign(int val, const error_category& ecat) noexcept { + m_ev = val; + m_ecat = &ecat; + } + //template + //error_code& operator= (ErrorCodeEnum e) noexcept; + void clear() noexcept { + m_ev = 0; + m_ecat = 0; + } + int value() const noexcept { + return m_ev; + } + const error_category& category() const noexcept { + return *m_ecat; + } + error_condition default_error_condition() const noexcept { + return category().default_error_condition(value()); + } + ::std::string message() const { + return category().message(value()); + } + operator bool() const noexcept { + return m_ev != 0; + } +}; + +class system_error: + public ::std::exception +{ + const error_code m_error_code; + ::std::string m_what_str; +public: + system_error(::std::error_code ec); + system_error(::std::error_code ec, const ::std::string& what_arg); + system_error(::std::error_code ec, const char* what_arg); + system_error(int ev, const ::std::error_category& ecat); + system_error(int ev, const ::std::error_category& ecat, const ::std::string& what_arg); + system_error(int ev, const ::std::error_category& ecat, const char* what_arg); + ~system_error() noexcept; + + const char* what() const noexcept; +}; + +bool operator==(const error_condition& lhs, const error_condition& rhs) noexcept { + return lhs.category() == rhs.category() && lhs.value() == rhs.value(); +} +bool operator!=(const error_condition& lhs, const error_condition& rhs) noexcept { + return !(lhs == rhs); +} +bool operator< (const error_condition& lhs, const error_condition& rhs) noexcept { + return lhs.category() < rhs.category() || lhs.value() < rhs.value(); +} +bool operator==(const error_condition& lhs, const error_code& rhs) noexcept { + return lhs.category().equivalent(rhs, lhs.value()) || rhs.category().equivalent(rhs.value(), lhs); +} +bool operator==(const error_code& lhs, const error_condition& rhs) noexcept { + return lhs.category().equivalent(lhs.value(),rhs) || rhs.category().equivalent(lhs,rhs.value()); +} +bool operator!=(const error_condition& lhs, const error_code& rhs) noexcept { + return !(lhs == rhs); +} +bool operator!=(const error_code& lhs, const error_condition& rhs) noexcept { + return !(lhs == rhs); +} + + + +}; // namespace std + +#endif + +// vim: ft=cpp + diff --git a/Usermode/Libraries/libc++.so_src/include_exp/vector b/Usermode/Libraries/libc++.so_src/include_exp/vector index c1301238..870c49b8 100644 --- a/Usermode/Libraries/libc++.so_src/include_exp/vector +++ b/Usermode/Libraries/libc++.so_src/include_exp/vector @@ -13,7 +13,61 @@ namespace std { namespace _bits { -template class vector_iterator; +template +class vector_iterator//: + //public random_acess_iterator_tag +{ + T* m_array; + size_type m_pos; + size_type m_max; +public: + vector_iterator(): + vector_iterator(0,0,0) + { + } + vector_iterator(const vector_iterator& x): + vector_iterator() + { + *this = x; + } + vector_iterator(T* array, size_type start, size_type max): + m_array(array), + m_pos(start), + m_max(max) + { + } + vector_iterator& operator=(const vector_iterator& x) + { + m_array = x.m_array; + m_pos = x.m_pos; + m_max = x.m_max; + return *this; + } + bool operator==(const vector_iterator& other) const { + return m_array == other.m_array && m_pos == other.m_pos; + } + bool operator!=(const vector_iterator& other) const { + return !(*this == other); + } + T& operator*() const { + return m_array[m_pos]; + } + T& operator->() const { + return m_array[m_pos]; + } + vector_iterator& operator++() { + if(m_pos < m_max) { + m_pos ++; + } + return *this; + } + vector_iterator& operator--() { + if(m_pos > 0) { + m_pos --; + } + return *this; + } +}; } template > @@ -26,10 +80,10 @@ public: typedef typename allocator_type::const_reference const_reference; typedef typename allocator_type::pointer pointer; typedef typename allocator_type::const_pointer const_pointer; - typedef ::std::_bits::vector_iterator iterator; - typedef ::std::_bits::vector_iterator const_iterator; typedef int difference_type; typedef size_t size_type; + typedef ::std::_bits::vector_iterator iterator; + typedef ::std::_bits::vector_iterator const_iterator; private: allocator_type m_alloc; @@ -58,12 +112,126 @@ public: ~vector() { - for( size_type i = 0; i < m_size; i ++ ) { - m_alloc.destroy( &m_data[i] ); + clear(); + m_alloc.deallocate(m_data, m_capacity); + } + + // Iterators + iterator begin() { + return iterator(m_data, 0, m_size); + } + const_iterator begin() const { + return const_iterator(m_data, 0, m_size); + } + iterator end() { + return iterator(m_data, m_size, m_size); + } + const_iterator end() const { + return const_iterator(m_data, m_size, m_size); + } + + // Capacity + size_type size() const { + return m_size; + } + size_type max_size() const { + return -1 / sizeof(value_type); + } + void resize(size_type new_cap, value_type val = value_type()) { + reserve(new_cap); + if( new_cap > m_size ) + { + for( size_type i = m_size; i < new_cap; i ++ ) { + m_alloc.construct( &m_data[i], val ); + } + } + else + { + for( size_type i = new_cap; i < m_size; i ++ ) + m_alloc.destroy( &m_data[i] ); } + m_size = new_cap; + } + size_type capacity() const { + return m_capacity; + } + bool empty() const { + return m_size == 0; + } + void reserve(size_type n) { + //if( n > max_size() ) + // throw ::std::length_error(); + } + void shrink_to_fit() { } + // Element access + reference operator[] (size_type n) { + return m_data[n]; + } + const_reference operator[] (size_type n) const { + return m_data[n]; + } + reference at(size_type n) { + if(n > size()) + _throw_out_of_range("::std::vector - at"); + return m_data[n]; + } + const_reference at(size_type n) const { + if(n > size()) + _throw_out_of_range("::std::vector - at"); + return m_data[n]; + } + reference front() { + return m_data[0]; + } + const_reference front() const { + return m_data[0]; + } + reference back() { + return m_data[size()-1]; + } + const_reference back() const { + return m_data[size()-1]; + } + pointer data() noexcept { + return m_data; + } + const_pointer data() const noexcept { + return m_data; + } + // Modifiers + void assign(size_type n, const value_type& val) { + clear(); + resize(n, val); + } + void push_back(const value_type& val) { + resize(size()+1, val); + } + void pop_back() { + if( !empty() ) { + resize(size()-1); + } + } + iterator insert(iterator position, const value_type& val) { + inesert(position, 1, val); + return position; + } + void insert(iterator position, size_type n, const value_type& val); + iterator erase(iterator position); + iterator erase(iterator first, iterator last); + //void swap(vector& x) { + // ::std::swap(m_size, x.m_size); + // ::std::swap(m_capacity, x.m_capacity); + // ::std::swap(m_data, x.m_data); + //} + void clear() { + for( size_type i = 0; i < m_size; i ++ ) { + m_alloc.destroy( &m_data[i] ); + } + m_size = 0; + } }; }; // namespace std diff --git a/Usermode/Libraries/libc++.so_src/system_error.cc b/Usermode/Libraries/libc++.so_src/system_error.cc new file mode 100644 index 00000000..59f25f96 --- /dev/null +++ b/Usermode/Libraries/libc++.so_src/system_error.cc @@ -0,0 +1,106 @@ +/* + * Acess2 C++ Library + * - By John Hodge (thePowersGang) + * + * system_error.cc + * - ::std::system_error and other helpers + */ +#include +#include + +namespace std { + +system_error::system_error(::std::error_code ec): + m_error_code(ec), + m_what_str( (::std::string)ec.category().name() + ":" + ec.message()) +{ +} +system_error::system_error(::std::error_code ec, const ::std::string& what_arg): + m_error_code(ec) +{ + m_what_str += " - "; + m_what_str += what_arg; +} +system_error::system_error(::std::error_code ec, const char* what_arg): + m_error_code(ec) +{ + m_what_str += " - "; + m_what_str += what_arg; +} +system_error::system_error(int ev, const ::std::error_category& ecat): + m_error_code(ev, ecat) +{ +} +system_error::system_error(int ev, const ::std::error_category& ecat, const ::std::string& what_arg): + m_error_code(ev, ecat) +{ + m_what_str += " - "; + m_what_str += what_arg; +} +system_error::system_error(int ev, const ::std::error_category& ecat, const char* what_arg): + m_error_code(ev, ecat) +{ + m_what_str += " - "; + m_what_str += what_arg; +} + +system_error::~system_error() noexcept +{ +} + +const char* system_error::what() const noexcept +{ + return m_what_str.c_str(); +} + + +bool error_category::equivalent(const error_code& code, int valcond) const noexcept { + return *this == code.category() && code.value() == valcond; +} + + +class class_generic_category: + public error_category +{ +public: + class_generic_category() { + } + ~class_generic_category() noexcept { + } + const char *name() const noexcept { + return "generic"; + } + ::std::string message(int val) const { + return ::std::string( ::strerror(val) ); + } +} g_generic_category; + +const ::std::error_category& generic_category() noexcept +{ + return g_generic_category; +} + + +class class_system_category: + public error_category +{ +public: + class_system_category() { + } + ~class_system_category() noexcept { + } + const char *name() const noexcept { + return "system"; + } + ::std::string message(int val) const { + return ::std::string( ::strerror(val) ); + } +} g_system_category; + +const ::std::error_category& system_category() noexcept +{ + return g_system_category; +} + +}; // namespace std + -- 2.20.1