Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reimplement string with shared_ptr instead of concrete macro #263

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 39 additions & 30 deletions Kernel/Types/string.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,33 @@ string_rep::resize (int m) {
n= m;
}

string::string (char c) {
rep = tm_new<string_rep> (1);
rep->a[0]= c;
string::string (char c)
: string_ptr (std::allocate_shared<string_rep> (string_allocator, 1)) {
get ()->a[0]= c;
}

string::string (char c, int n) {
rep= tm_new<string_rep> (n);
string::string (char c, int n)
: string_ptr (std::allocate_shared<string_rep> (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<string_rep> (n);
string::string (const char* a)
: string_ptr (
std::allocate_shared<string_rep> (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<string_rep> (n);
string::string (const char* a, int n)
: string_ptr (std::allocate_shared<string_rep> (string_allocator, n)) {
int i;
char* S= get ()->a;
for (i= 0; i < n; i++)
rep->a[i]= a[i];
S[i]= a[i];
}

/******************************************************************************
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -104,32 +108,37 @@ 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;
}

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;
}

Expand Down
39 changes: 22 additions & 17 deletions Kernel/Types/string.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,10 @@
#ifndef STRING_H
#define STRING_H
#include "basic.hpp"
#include <memory>

class string;
class string_rep : concrete_struct {
class string_rep {
int n;
char* a;

Expand All @@ -31,37 +32,41 @@ class string_rep : concrete_struct {
friend inline int N (string a);
};

class string {
CONCRETE (string);
inline string () : rep (tm_new<string_rep> ()) {}
inline string (int n) : rep (tm_new<string_rep> (n)) {}
using string_ptr= std::shared_ptr<string_rep>;
static const tm_allocator<string_rep> string_allocator;
class string : public string_ptr {
public:
inline string ()
: string_ptr (std::allocate_shared<string_rep> (string_allocator)) {}
inline string (int n)
: string_ptr (std::allocate_shared<string_rep> (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);
Expand Down
10 changes: 7 additions & 3 deletions Kernel/Types/tree.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,16 @@ tree::operator[] (int i) {
}
inline int
N (tree t) {
CHECK_COMPOUND (t);
return N ((static_cast<compound_rep*> (t.rep))->a);
if (is_atomic (t)) {
return N ((static_cast<atomic_rep*> (t.rep))->label);
}
else {
return N ((static_cast<compound_rep*> (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<compound_rep*> (t.rep))->a);
}
inline int
Expand Down
80 changes: 80 additions & 0 deletions System/Memory/fast_alloc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <type_traits>
#include <utility>

template <class T> 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 <class U, class... Args> void construct (U* p, Args&&... args) {
::new (p) U (std::forward<Args> (args)...);
}
template <class U> 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 <class U> struct rebind {
typedef tm_allocator<U> other;
};

tm_allocator () tm_attr_noexcept = default;
tm_allocator (const tm_allocator&) tm_attr_noexcept= default;
template <class U> tm_allocator (const tm_allocator<U>&) 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<T*> (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<pointer> (fast_new (count * sizeof (T)));
}
#endif

#if ((__cplusplus >= 201103L) || (_MSC_VER > 1900)) // C++11
using is_always_equal= std::true_type;
#endif
};

template <class T1, class T2>
bool
operator== (const tm_allocator<T1>&, const tm_allocator<T2>&) tm_attr_noexcept {
return true;
}
template <class T1, class T2>
bool
operator!= (const tm_allocator<T1>&, const tm_allocator<T2>&) tm_attr_noexcept {
return false;
}

#endif // defined FAST_ALLOC_H
10 changes: 5 additions & 5 deletions tests/Kernel/Types/tree_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand All @@ -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()") {
Expand Down
Loading