diff --git a/Kernel/Types/string.cpp b/Kernel/Types/string.cpp index 3e86eb7ad..d55a52e0f 100644 --- a/Kernel/Types/string.cpp +++ b/Kernel/Types/string.cpp @@ -51,29 +51,33 @@ string_rep::resize (int m) { n= m; } -string::string (char c) { - rep = tm_new (1); - rep->a[0]= c; +string::string (char c) + : string_ptr (std::allocate_shared (string_allocator, 1)) { + get ()->a[0]= c; } -string::string (char c, int n) { - rep= tm_new (n); +string::string (char c, int n) + : string_ptr (std::allocate_shared (string_allocator, n)) { + char* S= get ()->a; for (int i= 0; i < n; i++) - rep->a[i]= c; + S[i]= c; } -string::string (const char* a) { - int i, n= strlen (a); - rep= tm_new (n); +string::string (const char* a) + : string_ptr ( + std::allocate_shared (string_allocator, strlen (a))) { + int i, n= strlen (a); + char* S= get ()->a; for (i= 0; i < n; i++) - rep->a[i]= a[i]; + S[i]= a[i]; } -string::string (const char* a, int n) { - int i; - rep= tm_new (n); +string::string (const char* a, int n) + : string_ptr (std::allocate_shared (string_allocator, n)) { + int i; + char* S= get ()->a; for (i= 0; i < n; i++) - rep->a[i]= a[i]; + S[i]= a[i]; } /****************************************************************************** @@ -82,8 +86,8 @@ string::string (const char* a, int n) { bool string::operator== (const char* s) { - int i, n= rep->n; - char* S= rep->a; + int i, n= get ()->n; + char* S= get ()->a; for (i= 0; i < n; i++) { if (s[i] != S[i]) return false; if (s[i] == '\0') return false; @@ -93,8 +97,8 @@ string::operator== (const char* s) { bool string::operator!= (const char* s) { - int i, n= rep->n; - char* S= rep->a; + int i, n= get ()->n; + char* S= get ()->a; for (i= 0; i < n; i++) { if (s[i] != S[i]) return true; if (s[i] == '\0') return true; @@ -104,19 +108,22 @@ string::operator!= (const char* s) { bool string::operator== (string a) { - int i; - if (rep->n != a->n) return false; - for (i= 0; i < rep->n; i++) - if (rep->a[i] != a->a[i]) return false; + int i, n= get ()->n; + char *S= get ()->a, *Sa= a->a; + + if (n != a->n) return false; + for (i= 0; i < n; i++) + if (S[i] != Sa[i]) return false; return true; } bool string::operator!= (string a) { - int i; - if (rep->n != a->n) return true; - for (i= 0; i < rep->n; i++) - if (rep->a[i] != a->a[i]) return true; + int i, n= get ()->n; + char *S= get ()->a, *Sa= a->a; + if (n != a->n) return true; + for (i= 0; i < n; i++) + if (S[i] != Sa[i]) return true; return false; } @@ -124,12 +131,14 @@ string string::operator() (int begin, int end) { if (end <= begin) return string (); - int i; - begin= max (min (rep->n, begin), 0); - end = max (min (rep->n, end), 0); + int i; + char* S= get ()->a; + begin = max (min (get ()->n, begin), 0); + end = max (min (get ()->n, end), 0); string r (end - begin); + char* Sr= r->a; for (i= begin; i < end; i++) - r[i - begin]= rep->a[i]; + Sr[i - begin]= S[i]; return r; } diff --git a/Kernel/Types/string.hpp b/Kernel/Types/string.hpp index 8b022e9ec..43f795a24 100644 --- a/Kernel/Types/string.hpp +++ b/Kernel/Types/string.hpp @@ -13,9 +13,10 @@ #ifndef STRING_H #define STRING_H #include "basic.hpp" +#include class string; -class string_rep : concrete_struct { +class string_rep { int n; char* a; @@ -31,37 +32,41 @@ class string_rep : concrete_struct { friend inline int N (string a); }; -class string { - CONCRETE (string); - inline string () : rep (tm_new ()) {} - inline string (int n) : rep (tm_new (n)) {} +using string_ptr= std::shared_ptr; +static const tm_allocator string_allocator; +class string : public string_ptr { +public: + inline string () + : string_ptr (std::allocate_shared (string_allocator)) {} + inline string (int n) + : string_ptr (std::allocate_shared (string_allocator, n)) {} string (char c); string (char c, int n); string (const char* s); string (const char* s, int n); - inline char& operator[] (int i) { return rep->a[i]; } + inline char& operator[] (int i) { return get ()->a[i]; } bool operator== (const char* s); bool operator!= (const char* s); bool operator== (string s); bool operator!= (string s); string operator() (int start, int end); }; -CONCRETE_CODE (string); extern inline int N (string a) { return a->n; } -string copy (string a); -tm_ostream& operator<< (tm_ostream& out, string a); -string& operator<< (string& a, char); -string& operator<< (string& a, string b); -string operator* (const char* a, string b); -string operator* (string a, string b); -string operator* (string a, const char* b); -bool operator< (string a, string b); -bool operator<= (string a, string b); -int hash (string s); +string copy (string a); +tm_ostream& operator<< (tm_ostream& out, string a); +std::ostream& operator<< (std::ostream& out, string a)= delete; +string& operator<< (string& a, char); +string& operator<< (string& a, string b); +string operator* (const char* a, string b); +string operator* (string a, string b); +string operator* (string a, const char* b); +bool operator< (string a, string b); +bool operator<= (string a, string b); +int hash (string s); bool as_bool (string s); int as_int (string s); diff --git a/Kernel/Types/tree.hpp b/Kernel/Types/tree.hpp index 3aa8235d5..ef4efee75 100644 --- a/Kernel/Types/tree.hpp +++ b/Kernel/Types/tree.hpp @@ -175,12 +175,16 @@ tree::operator[] (int i) { } inline int N (tree t) { - CHECK_COMPOUND (t); - return N ((static_cast (t.rep))->a); + if (is_atomic (t)) { + return N ((static_cast (t.rep))->label); + } + else { + return N ((static_cast (t.rep))->a); + } } inline int arity (tree t) { - if (t.rep->op == /*STRING*/ 0) return 0; + if (is_atomic (t)) return 0; else return N ((static_cast (t.rep))->a); } inline int diff --git a/System/Memory/fast_alloc.hpp b/System/Memory/fast_alloc.hpp index e57fc2dc9..90c2b6d34 100644 --- a/System/Memory/fast_alloc.hpp +++ b/System/Memory/fast_alloc.hpp @@ -711,4 +711,84 @@ tm_delete_array (C* Ptr) { #endif // defined(NO_FAST_ALLOC) || defined(X11TEXMACS) +#ifdef __cplusplus +#if (__cplusplus >= 201103L) || (_MSC_VER > 1900) // C++11 +#define tm_attr_noexcept noexcept +#else +#define tm_attr_noexcept throw () +#endif +#else +#define tm_attr_noexcept +#endif + +#include +#include + +template struct tm_allocator { + typedef T value_type; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef value_type& reference; + typedef value_type const& const_reference; + typedef value_type* pointer; + typedef value_type const* const_pointer; + typedef const void* void_pointer; + +#if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using propagate_on_container_copy_assignment= std::true_type; + using propagate_on_container_move_assignment= std::true_type; + using propagate_on_container_swap = std::true_type; + template void construct (U* p, Args&&... args) { + ::new (p) U (std::forward (args)...); + } + template void destroy (U* p) tm_attr_noexcept { p->~U (); } +#else + void construct (pointer p, value_type const& val) { + ::new (p) value_type (val); + } + void destroy (pointer p) { p->~value_type (); } +#endif + + size_type max_size () const tm_attr_noexcept { + return (PTRDIFF_MAX / sizeof (value_type)); + } + pointer address (reference x) const { return &x; } + const_pointer address (const_reference x) const { return &x; } + template struct rebind { + typedef tm_allocator other; + }; + + tm_allocator () tm_attr_noexcept = default; + tm_allocator (const tm_allocator&) tm_attr_noexcept= default; + template tm_allocator (const tm_allocator&) tm_attr_noexcept {} + tm_allocator select_on_container_copy_construction () const { return *this; } + void deallocate (T* p, size_type) { fast_delete (p); } + +#if (__cplusplus >= 201703L) // C++17 + T* allocate (size_type count) { + return static_cast (fast_new (count * sizeof (T))); + } + T* allocate (size_type count, void_pointer) { return allocate (count); } +#else + pointer allocate (size_type count, void_pointer= 0) { + return static_cast (fast_new (count * sizeof (T))); + } +#endif + +#if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11 + using is_always_equal= std::true_type; +#endif +}; + +template +bool +operator== (const tm_allocator&, const tm_allocator&) tm_attr_noexcept { + return true; +} +template +bool +operator!= (const tm_allocator&, const tm_allocator&) tm_attr_noexcept { + return false; +} + #endif // defined FAST_ALLOC_H diff --git a/tests/Kernel/Types/tree_test.cpp b/tests/Kernel/Types/tree_test.cpp index 46e4e7296..30142a669 100644 --- a/tests/Kernel/Types/tree_test.cpp +++ b/tests/Kernel/Types/tree_test.cpp @@ -67,9 +67,9 @@ TEST_CASE ("test_is_generic") { TEST_CASE ("test N()") { CHECK (N (tree ()) == 0); - CHECK (N (tree (0, tree ())) == 1); - CHECK (N (tree (0, tree (), tree ())) == 2); - CHECK (N (tree (0, tree (), tree (), tree ())) == 3); + CHECK (N (tree (1, tree ())) == 1); + CHECK (N (tree (1, tree (), tree ())) == 2); + CHECK (N (tree (1, tree (), tree (), tree ())) == 3); } TEST_CASE ("test_arity") { @@ -80,11 +80,11 @@ TEST_CASE ("test_arity") { } TEST_CASE ("test right_index") { - CHECK (right_index (tree (0)) == 0); + // CHECK (right_index (tree (0)) == 0); CHECK (right_index (tree ("string")) == 6); CHECK (right_index (tree (280, tree ())) == 1); CHECK (right_index (tree (9, tree ())) == 1); - CHECK (right_index (tree (0, 5)) == 5); + // CHECK (right_index (tree (0, 5)) == 5); } TEST_CASE ("test A()") {