Usermode/libc++ - Many fixes and cleanups
authorJohn Hodge <[email protected]>
Mon, 18 Aug 2014 10:27:11 +0000 (18:27 +0800)
committerJohn Hodge <[email protected]>
Mon, 18 Aug 2014 10:27:11 +0000 (18:27 +0800)
- Debug wrapper in cxxapi code
- Fix exception when appending to a list
- Clean up dependencies for std::exception (recursive with std::string)
- Add initializer_list support (C++11)

14 files changed:
Usermode/Libraries/libc++.so_src/exception_handling.cc
Usermode/Libraries/libc++.so_src/exceptions.cc
Usermode/Libraries/libc++.so_src/gxx_personality.cc
Usermode/Libraries/libc++.so_src/include_exp/exception
Usermode/Libraries/libc++.so_src/include_exp/initializer_list [new file with mode: 0644]
Usermode/Libraries/libc++.so_src/include_exp/list
Usermode/Libraries/libc++.so_src/include_exp/new
Usermode/Libraries/libc++.so_src/include_exp/stdexcept
Usermode/Libraries/libc++.so_src/include_exp/string
Usermode/Libraries/libc++.so_src/include_exp/system_error
Usermode/Libraries/libc++.so_src/include_exp/vector
Usermode/Libraries/libc++.so_src/new.cc
Usermode/Libraries/libc++.so_src/string.cc
Usermode/Libraries/libc++.so_src/typeinfo.cc

index c327f84..81d4605 100644 (file)
 
 #include <acess/sys.h>
 
+#define DEBUG_ENABLED  1
+
+#if DEBUG_ENABLED
+# define       DEBUG(v...)     ::_SysDebug(v)
+#else
+# define       DEBUG(v...)     do{}while(0)
+#endif
+
 /*__thread*/ struct __cxa_eh_globals {
        __cxa_exception *caughtExceptions;
        unsigned  int   uncaughtExceptions;
@@ -58,7 +66,7 @@ extern "C" void __cxa_call_unexpected(void *)
 
 extern "C" void *__cxa_allocate_exception(size_t thrown_size)
 {
-       ::_SysDebug("__cxa_allocate_exception(%i)", thrown_size);
+       DEBUG("__cxa_allocate_exception(%i)", thrown_size);
        __cxa_exception *ret = static_cast<__cxa_exception*>( malloc( sizeof(__cxa_exception) + thrown_size ) );
        if( !ret ) {
                if( thrown_size <= sizeof(emergency_exception.buf) && TEST_AND_SET(emergency_exception_used) )
@@ -70,13 +78,13 @@ extern "C" void *__cxa_allocate_exception(size_t thrown_size)
                _SysDebug("__cxa_allocate_exception - No free space");
                ::std::terminate();
        }
-       ::_SysDebug("__cxa_allocate_exception: return %p", ret+1);
+       DEBUG("__cxa_allocate_exception: return %p", ret+1);
        return ret + 1;
 }
 
 extern "C" void __cxa_free_exception(void *thrown_exception)
 {
-       ::_SysDebug("__cxa_free_exception(%p)", thrown_exception);
+       DEBUG("__cxa_free_exception(%p)", thrown_exception);
        if(thrown_exception == &emergency_exception.buf) {
                //assert(emergency_exception_used);
                emergency_exception_used = false;
@@ -89,13 +97,15 @@ extern "C" void __cxa_free_exception(void *thrown_exception)
 
 extern "C" void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void*))
 {
-       ::_SysDebug("__cxa_throw(%p,%p,%p) '%s' by %p",
+       #if DEBUG_ENABLED
+       DEBUG("__cxa_throw(%p,%p,%p) '%s' by %p",
                thrown_exception, tinfo, dest, tinfo->name(), __builtin_return_address(0)
                );
        {
                const ::std::exception* e = reinterpret_cast<const ::std::exception*>(thrown_exception);
-               ::_SysDebug("- e.what() = '%s'", e->what());
+               DEBUG("- e.what() = '%s'", e->what());
        }
+       #endif
 
        __cxa_exception *except = static_cast<__cxa_exception*>( thrown_exception ) - 1;
        
@@ -115,7 +125,7 @@ extern "C" void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void
 extern "C" void *__cxa_begin_catch(_Unwind_Exception *exceptionObject)
 {
        __cxa_exception *except = reinterpret_cast<__cxa_exception*>( exceptionObject+1 )-1;
-       ::_SysDebug("__cxa_begin_catch(%p) - except=%p", exceptionObject, except);
+       DEBUG("__cxa_begin_catch(%p) - except=%p", exceptionObject, except);
        
        except->handlerCount ++;
        
@@ -130,7 +140,7 @@ extern "C" void *__cxa_begin_catch(_Unwind_Exception *exceptionObject)
 extern "C" void __cxa_end_catch()
 {
        struct __cxa_exception  *except = __cxa_get_globals()->caughtExceptions;
-       ::_SysDebug("__cxa_end_catch - %p", except);
+       DEBUG("__cxa_end_catch - %p", except);
        except->handlerCount --;
        __cxa_get_globals()->caughtExceptions = except->nextException;
        
index 117ceeb..cc7c8c2 100644 (file)
@@ -3,7 +3,7 @@
  * - By John Hodge (thePowersGang)
  *
  * exceptions.cc
- * - ::std::exception and friends
+ * - exception and friends
  */
 #include <string>
 #include <exception>
 #include <acess/sys.h>
 
 // === CODE ===
-::std::exception::exception() throw():
-       m_what_str("-empty-")
-{
-}
-::std::exception::exception(const exception& other) throw():
-       m_what_str(other.m_what_str)
+namespace std {
+
+exception::exception() throw()
 {
 }
-::std::exception::exception(const string& str) throw():
-       m_what_str(str)
+exception::exception(const exception&) throw()
 {
 }
-::std::exception& ::std::exception::operator=(const exception& other) throw()
+exception& exception::operator=(const exception&) throw()
 {
-       m_what_str = other.m_what_str;
        return *this;
 }
-::std::exception::~exception() throw()
+exception::~exception() throw()
 {
 }
-const char* ::std::exception::what() const throw()
+const char* exception::what() const throw()
 {
-       return m_what_str.c_str();
+       return "generic exception";
 }
 
-void ::std::terminate()
+void terminate()
 {
-       _SysDebug("::std::terminate()");
+       _SysDebug("terminate()");
        _exit(0);
 }
 
+_bits::str_except::str_except(const string& what_arg):
+       m_str(what_arg)
+{
+}
+_bits::str_except::~str_except() noexcept
+{
+}
+_bits::str_except& _bits::str_except::operator=(const str_except& e) noexcept
+{
+       m_str = e.m_str;
+       return *this;
+}
+const char* _bits::str_except::what() const throw()
+{
+       return m_str.c_str();
+}
+
 // --- Standar Exceptions ---
-::std::logic_error::logic_error(const ::std::string& what_str):
-       exception(what_str)
+logic_error::logic_error(const string& what_str):
+       _bits::str_except(what_str)
 {
 }
 
-::std::out_of_range::out_of_range(const ::std::string& what_str):
+out_of_range::out_of_range(const string& what_str):
        logic_error(what_str)
 {
 }
 
-::std::length_error::length_error(const ::std::string& what_str):
+length_error::length_error(const string& what_str):
        logic_error(what_str)
 {
 }
 
-::std::runtime_error::runtime_error(const ::std::string& what_str):
-       exception(what_str)
+runtime_error::runtime_error(const string& what_str):
+       _bits::str_except(what_str)
 {
 }
 
+}      // namespace std
+
index 0ecb86a..f065e89 100644 (file)
 #include <cassert>
 #include <cxxabi.h>    // __dynamic_cast
 
+#define DEBUG_ENABLED  1
+
+#if DEBUG_ENABLED
+# define DEBUG(v...)   ::_SysDebug(v)
+#else
+# define DEBUG(v...)   do{}while(0)
+#endif
+
 // === PROTOTYPES ===
 extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version, _Unwind_Action actions, uint64_t exceptionClass,
                struct _Unwind_Exception *exceptionObject, struct _Unwind_Context *context);
@@ -79,12 +87,12 @@ extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version, _Unwind_Action
                // If a handler was found
                if( frame_action == 2 ) {
                        // - return _URC_HANDLER_FOUND
-                       _SysDebug("SEARCH: 0x%llx Handler %p(%i)",
+                       DEBUG("SEARCH: 0x%llx Handler %p(%i)",
                                _Unwind_GetIP(context), landingpad, switch_value);
                        return _URC_HANDLER_FOUND;
                }
                // - If no handler (either nothing, or cleanups), return _URC_CONTINUE_UNWIND
-               _SysDebug("SEARCH: 0x%llx no handler %p(%i)",
+               DEBUG("SEARCH: 0x%llx no handler %p(%i)",
                        _Unwind_GetIP(context), landingpad, switch_value);
                return _URC_CONTINUE_UNWIND;
        }
@@ -105,7 +113,7 @@ extern "C" _Unwind_Reason_Code __gxx_personality_v0(int version, _Unwind_Action
                        switch_value = 0;
                }
        
-               _SysDebug("Install context IP=0x%x, R%i=%p/R%i=%i",
+               DEBUG("Install context IP=0x%x, R%i=%p/R%i=%i",
                        (uintptr_t)landingpad,
                        __builtin_eh_return_data_regno(0), exceptionObject,
                        __builtin_eh_return_data_regno(1), switch_value
@@ -124,7 +132,7 @@ int get_frame_action(const sLSDA_Header &header, _Unwind_Context *context, const
        uint64_t &landingpad, int64_t &switch_value)
 {
        uint64_t ip = _Unwind_GetIP(context) - _Unwind_GetRegionStart(context);
-       _SysDebug("get_frame_action: IP = 0x%llx + 0x%llx", _Unwind_GetRegionStart(context), ip);
+       DEBUG("get_frame_action: IP = 0x%llx + 0x%llx", _Unwind_GetRegionStart(context), ip);
        // Check if there is a handler for this exception in this frame
        // - Search call site table for this return address (corresponds to a try block)
        uintptr_t       cs_ldgpad;
@@ -153,13 +161,13 @@ int get_frame_action(const sLSDA_Header &header, _Unwind_Context *context, const
        }
        if( lsda_ptr >= header.ActionTable ) {
                // No match!
-               _SysDebug("__gxx_personality_v0: No entry for IP 0x%x", ip);
+               DEBUG("__gxx_personality_v0: No entry for IP 0x%x", ip);
                return 0;
        }
        
        // Found it
        if( cs_ldgpad == 0 ) {
-               _SysDebug("No landingpad, hence no action");
+               DEBUG("No landingpad, hence no action");
                if( cs_action != 0 ) {
                        _SysDebug("%s: NOTICE cs_ldgpad==0 but cs_action(0x%llx)!=0",
                                __func__, cs_action);
@@ -167,7 +175,7 @@ int get_frame_action(const sLSDA_Header &header, _Unwind_Context *context, const
                return 0;
        }
        else if( cs_action == 0 ) {
-               _SysDebug("No action, cleanups only");
+               DEBUG("No action, cleanups only");
                switch_value = 0;
                landingpad = header.LPStart + cs_ldgpad;
                return 1;       // 1 = cleanup only
@@ -247,20 +255,21 @@ const ::std::type_info *get_exception_type(const void *exception_object)
 bool exception_matches_single(const std::type_info *throw_type, const struct sLSDA_Header &header, int type_index)
 {
        const ::std::type_info *catch_type = get_type_info(header, type_index);
+       DEBUG("catch_type = %p", catch_type);
 
        if( !catch_type )
        {
-               _SysDebug("catch(...)");
+               DEBUG("catch(...)");
                return true;
        }
        else if( !throw_type )
        {
-               _SysDebug("threw UNK");
+               DEBUG("threw UNK");
                return false;
        }
        else
        {
-               _SysDebug("catch(%s), throw %s", catch_type->name(), throw_type->name());
+               DEBUG("catch(%s), throw %s", catch_type->name(), throw_type->name());
                size_t ofs = 0;
                if( !catch_type->__is_child(*throw_type, ofs) ) {
                        _SysDebug("> No match");
index 63e35bd..9e1469d 100644 (file)
 
 #define noexcept       throw()
 
-#include "string"
-
 namespace std {
 
 class exception
 {
-       string  m_what_str;
 public:
        exception() noexcept;
        exception(const exception& e) noexcept;
        exception& operator= (const exception& e) noexcept;
        virtual ~exception() noexcept;
        virtual const char* what() const noexcept;
-protected:
-       exception(const string& what_str) noexcept;
 };
 
 class bad_exception:
@@ -32,6 +27,7 @@ class bad_exception:
 {
 public:
        bad_exception() noexcept;
+       const char* what() const noexcept;
 };
 
 typedef void (*terminate_handler)();
diff --git a/Usermode/Libraries/libc++.so_src/include_exp/initializer_list b/Usermode/Libraries/libc++.so_src/include_exp/initializer_list
new file mode 100644 (file)
index 0000000..565980f
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Acess2 C++ Library
+ * - By John Hodge (thePowersGang)
+ *
+ * vector (header)
+ * - C++'s vector (dynamic array) type
+ */
+#ifndef _LIBCXX__INITIALIZER_LIST_
+#define _LIBCXX__INITIALIZER_LIST_
+
+namespace std {
+
+template <class T>
+class initializer_list
+{
+public:
+       typedef T       value_type;
+       typedef const T&        reference;
+       typedef const T&        const_reference;
+       typedef size_t  size_type;
+       typedef const T*        iterator;
+       typedef const T*        const_iterator;
+private:
+       // ORDER MATTERS : The first item must be a pointer to the array, the second must be the size
+       value_type*     m_values;
+       size_type       m_len;
+public:        
+       constexpr initializer_list() noexcept:
+               m_len(0)
+       {
+       }
+
+       size_type size() const noexcept
+       {
+               return m_len;
+       }
+       
+       const T* begin() const noexcept
+       {
+               return &m_values[0];
+       }
+       const T* end() const noexcept
+       {
+               return &m_values[m_len];
+       }
+};
+
+};
+
+template <class T> const T* begin(const ::std::initializer_list<T>& il) { return il.begin(); }
+template <class T> const T* end  (const ::std::initializer_list<T>& il) { return il.end(); }
+
+#endif
+// vim: ft=cpp
+
index 181f0e4..3bc614e 100644 (file)
@@ -250,7 +250,7 @@ private:
                        position.m_cur->prev->next = newi;
                        position.m_cur->prev = newi;
                }
-               return ++position;
+               return ++iterator(*this, newi);
        }
 };
 
index f1ed0ab..b895832 100644 (file)
@@ -8,6 +8,7 @@
 #ifndef _LIBCXX_NEW_
 #define _LIBCXX_NEW_
 
+
 #include "cstddef"
 
 //extern void* operator new(size_t size) throw (::std::bad_alloc);
@@ -22,6 +23,22 @@ inline void* operator new[](size_t /*size*/, void* ptr) throw() {
        return ptr;
 }
 
+#include "exception"
+
+namespace std {
+
+class bad_alloc:
+       public ::std::exception
+{
+public:
+       bad_alloc() noexcept;
+       ~bad_alloc() noexcept;
+       
+       const char *what() const noexcept;
+};
+
+}      // namespace std
+
 #endif
 
 // vim: ft=cpp
index aa7072b..7556207 100644 (file)
@@ -9,18 +9,34 @@
 #define _LIBCXX_STDEXCEPT_
 
 #include "exception"
+#include "string"
 
 namespace std {
 
-class logic_error:
+namespace _bits {
+
+class str_except:
        public exception
+{
+       ::std::string   m_str;
+public:
+       explicit str_except(const string& what_arg);
+       virtual ~str_except() noexcept;
+       str_except& operator= (const str_except& e) noexcept;
+       virtual const char* what() const noexcept;
+};
+
+} // namespace _bits
+
+class logic_error:
+       public _bits::str_except
 {
 public:
        explicit logic_error(const string& what_arg);
 };
 
 class runtime_error:
-       public exception
+       public _bits::str_except
 {
 public:
        explicit runtime_error(const string& what_arg);
index 3d289d6..f36077d 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "_libcxx_helpers.h"
 #include <allocator>
+#include <initializer_list>
 
 namespace std {
 
@@ -38,6 +39,14 @@ struct char_traits<char>
                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 <>
@@ -74,6 +83,9 @@ public:
        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
@@ -237,6 +249,9 @@ public:
        bool empty() const {
                return length() == 0;
        }
+       #if _CXX11_AVAIL
+       void shrink_to_fit();
+       #endif
        
        // Access
        reference operator[] (size_type pos) {
@@ -257,6 +272,22 @@ public:
                        _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) {
@@ -339,17 +370,136 @@ public:
                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 <class InputIterator>
+       iterator insert(iterator p, InputIterator first, InputIterator last);
+       #if _CXX11_AVAIL
+       basic_string& insert(const_iterator p, initializer_list<charT> 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 <class InputIterator>
+       basic_string& replace(const_iterator i1, const_reference i2, InputIterator first, InputIterator last);
+       basic_string& replace(const_iterator i1, const_iterator i2, initializer_list<charT> 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 char *c_str() const {
+       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 char *data() const {
+       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:
@@ -384,6 +534,8 @@ private:
 
 typedef basic_string<char>     string;
 
+#define _libcxx_str    basic_string<charT,traits,Alloc>
+
 template <class charT, class traits, class Alloc>
 basic_string<charT,traits,Alloc> operator+(const basic_string<charT,traits,Alloc>& lhs, const basic_string<charT,traits,Alloc>& rhs)
 {
@@ -430,6 +582,21 @@ basic_string<charT,traits,Alloc> operator+(const charT lhs, const basic_string<c
        return ret;
 }
 
+// Three overloads each
+// name: Actual operator, opp: reversed operator
+#define _libcxx_string_def_cmp(name, opp) \
+       template <class charT, class traits, class Alloc> \
+       bool operator name(const _libcxx_str& lhs, const _libcxx_str& rhs) { return lhs.compare(rhs) name 0; } \
+       template <class charT, class traits, class Alloc> \
+       bool operator name(const charT* lhs, const _libcxx_str& rhs) { return rhs.compare(lhs) opp 0; } \
+       template <class charT, class traits, class Alloc> \
+       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
index c058d0c..ab42c9c 100644 (file)
@@ -10,6 +10,7 @@
 
 #include <allocator>
 #include <stdexcept>
+#include <initializer_list>
 
 extern "C" void _SysDebug(const char *, ...);
 
@@ -186,12 +187,29 @@ public:
                x.m_capacity = 0;
                x.m_size = 0;
        }
+       vector(vector&& x, const allocator_type& alloc):
+               m_alloc(alloc),
+               m_size(x.m_size),
+               m_capacity(x.m_capacity),
+               m_data(x.m_data)
+       {
+               x.m_data = nullptr;
+               x.m_capacity = 0;
+               x.m_size = 0;
+       }
+       vector(std::initializer_list<value_type> il, const allocator_type& alloc = allocator_type()):
+               vector(alloc)
+       {
+               reserve(il.size());
+               insert(begin(), il.begin(), il.end());
+       }
        #endif
        vector& operator=(const vector& x)
        {
                clear();
                m_alloc.deallocate(m_data, m_capacity);
                m_capacity = 0;
+               m_data = nullptr;
                
                reserve(x.size());
                for( size_type i = 0; i < x.size(); i ++ )
@@ -205,6 +223,7 @@ public:
                clear();
                m_alloc.deallocate(m_data, m_capacity);
                m_capacity = 0;
+               m_data = nullptr;
        }
        
        // Iterators
index 9dae853..f1ebc45 100644 (file)
@@ -8,6 +8,10 @@
 #include <stddef.h>
 #include <stdlib.h>
 #include <acess/sys.h>
+#include <new>
+
+// === IMPORTS ===
+extern "C" bool        _libc_free(void *mem);  // from libc.so, actual free.
 
 // === CODE ===
 void *operator new( size_t size )
@@ -15,32 +19,39 @@ void *operator new( size_t size )
        //_SysDebug("libc++ - operator new(%i)", size);
        return malloc( size );
 }
-void *operator new( size_t size, void* ptr )
-{
-       //_SysDebug("libc++ - operator new(%i, %p)", size, ptr);
-       size = size;
-       return ptr;
-}
 
 void *operator new[]( size_t size )
 {
        //_SysDebug("libc++ - operator new[](%i)", size);
        return malloc( size );
 }
-void *operator new[]( size_t size, void* ptr )
-{
-       //_SysDebug("libc++ - operator new[](%i, %p)", size, ptr);
-       size = size;
-       return ptr;
-}
 
 void operator delete(void *ptr)
 {
-       free(ptr);
+       if( !_libc_free(ptr) ) {
+               _SysDebug("delete of invalid by %p", __builtin_return_address(0));
+               throw ::std::bad_alloc();
+       }
 }
 
 void operator delete[](void *ptr)
 {
-       free(ptr);
+       if( !_libc_free(ptr) ) {
+               _SysDebug("delete[] of invalid by %p", __builtin_return_address(0));
+               throw ::std::bad_alloc();
+       }
+}
+
+
+::std::bad_alloc::bad_alloc() noexcept
+{
+}
+::std::bad_alloc::~bad_alloc() noexcept
+{
+}
+
+const char *::std::bad_alloc::what() const noexcept
+{
+       return "allocation failure";
 }
 
index 94ca722..f063e34 100644 (file)
@@ -10,6 +10,6 @@
 
 void ::std::_throw_out_of_range(const char *message)
 {
-       throw ::std::out_of_range(message);
+       throw ::std::out_of_range( ::std::string(message) );
 }
 
index 993df3c..e860f58 100644 (file)
@@ -47,6 +47,7 @@ type_info::type_info(const type_info& rhs):
 }
 type_info& type_info::operator=(const type_info& rhs)
 {
+       _SysDebug("type_info::operator=, was %s now %s", __type_name, rhs.__type_name);
        __type_name = rhs.__type_name;
        return *this;
 }
@@ -72,13 +73,13 @@ bool type_info::is_subclass() const
 // Acess-defined
 bool type_info::__is_child(const type_info &poss_child, unsigned long &offset) const
 {
+       _SysDebug("typeids = this:%s , poss_child:%s", typeid(*this).name(), typeid(poss_child).name());
+
        // Check #1: Child is same type
        if( poss_child == *this ) {
                offset = 0;
                return true;
        }
-
-       _SysDebug("typeids = this:%s , poss_child:%s", typeid(*this).name(), typeid(poss_child).name());
        
        // Check #2: This type must be a class
        if( !this->is_class() ) {

UCC git Repository :: git.ucc.asn.au