Skip to content

Commit

Permalink
Merge branch 'v50dev' of https://github.com/stclib/STC into v50dev
Browse files Browse the repository at this point in the history
  • Loading branch information
tylov committed Nov 1, 2024
2 parents c5c0284 + 4bf06a4 commit 4e7cec6
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 70 deletions.
2 changes: 1 addition & 1 deletion docs/arc_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ arc_X arc_X_from_ptr(i_key* p); // create an arc
arc_X arc_X_make(i_key key); // create an arc from constructed key object. Faster than from_ptr().
arc_X arc_X_clone(arc_X other); // return other with increased use count
void arc_X_assign(arc_X* self, arc_X other); // shared assign (increases use count)
void arc_X_assign(arc_X* self, const arc_X* other); // shared assign (increases use count)
void arc_X_take(arc_X* self, arc_X unowned); // take ownership of unowned.
arc_X arc_X_move(arc_X* self); // transfer ownership to receiver; self becomes NULL
void arc_X_drop(arc_X* self); // destruct (decrease use count, free at 0)
Expand Down
7 changes: 4 additions & 3 deletions docs/box_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,13 @@ box_X box_X_from_ptr(i_key* ptr); // create a box
box_X box_X_make(i_key val); // create a box from unowned val object.
box_X box_X_clone(box_X other); // return deep copied clone
void box_X_assign(box_X* self, box_X* moved); // transfer ownership from moved to self; moved becomes NULL.
void box_X_assign(box_X* self, box_X* other); // transfer ownership from other to self; other set to NULL.
void box_X_take(box_X* self, box_X unowned); // take ownership of unowned box object.
box_X box_X_move(box_X* self); // transfer ownership to receiving box returned. self becomes NULL.
box_X box_X_move(box_X* self); // transfer ownership to receiving box. self set to NULL.
i_key* box_X_release(box_X* self); // release owned pointer; must be freed by receiver. self set NULL.
void box_X_drop(box_X* self); // destruct the contained object and free its heap memory.
void box_X_reset_to(box_X* self, i_key* p); // assign new box from ptr. Takes ownership of p.
void box_X_reset_to(box_X* self, i_key* ptr); // assign ptr, and take ownership of ptr.
size_t box_X_hash(const box_X* x); // hash value
int box_X_cmp(const box_X* x, const box_X* y); // compares pointer addresses if no `i_cmp` is specified
Expand Down
6 changes: 3 additions & 3 deletions docs/cstr_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ cstr cstr_from(const char* str); // const
cstr cstr_from_s(cstr s, isize pos, isize len); // construct a substring
cstr cstr_from_sv(csview sv); // construct from a string view
cstr cstr_from_zv(zsview zv); // construct from a zero-terminated zsview
cstr cstr_from_fmt(const char* fmt, ...); // printf() formatting
cstr cstr_from_fmt(const char* fmt, ...); // construct from printf() formatting
cstr cstr_from_replace(csview sv, csview search, csview repl, int32_t count);
cstr cstr_with_n(const char* str, isize n); // construct from first n bytes of str
cstr cstr_with_capacity(isize cap); // make empty string with pre-allocated capacity.
cstr cstr_with_size(isize len, char fill); // make string with fill characters
cstr cstr_join(const char* sep, const char* str1, ...); // construct by joining c-strings with separator
cstr cstr_join_s(const char* sep, cstr s1, ...); // construct by joining cstrs with separator
cstr cstr_join_vec(const char* sep, Vec* vec); // construct by joining vec/stack of cstrs with separator
cstr cstr_join_s(const char* sep, {cstr s1, ...}); // construct by joining cstrs with separator
cstr cstr_join_array(const char* sep, const char* arr[], isize n); // join c-string array with separator
cstr cstr_join_array_s(const char* sep, cstr arr[], isize n); // join cstr array with separator

Expand Down
70 changes: 38 additions & 32 deletions include/stc/arc.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,35 +110,34 @@ STC_INLINE Self _c_MEMB(_init)(void)
STC_INLINE long _c_MEMB(_use_count)(const Self* self)
{ return self->use_count ? *self->use_count : 0; }


// c++: std::make_shared<_m_value>(val)
STC_INLINE Self _c_MEMB(_make)(_m_value val) {
Self unowned;
struct _c_MEMB(_rep_)* rep = _i_malloc(struct _c_MEMB(_rep_), 1);
*(unowned.use_count = &rep->metadata.counter) = 1;
*(unowned.get = &rep->value) = val; // (.use_count, .get) are OFFSET bytes apart.
return unowned;
}

STC_INLINE Self _c_MEMB(_from_ptr)(_m_value* ptr) {
enum {OFFSET = offsetof(struct _c_MEMB(_rep_), value)};
Self arc = {ptr};
Self unowned = {ptr};
if (ptr) {
// Adds 4 dummy bytes to ensure that the if-test in _drop is safe.
// Adds 4 dummy bytes to ensure that the if-test in _drop() is safe.
struct _arc_metadata* meta = (struct _arc_metadata*)i_malloc(OFFSET + 4);
*(arc.use_count = &meta->counter) = 1;
*(unowned.use_count = &meta->counter) = 1;
}
return arc;
return unowned;
}

// c++: std::make_shared<_m_value>(val)
STC_INLINE Self _c_MEMB(_make)(_m_value val) {
Self arc;
struct _c_MEMB(_rep_)* rep = _i_malloc(struct _c_MEMB(_rep_), 1);
*(arc.use_count = &rep->metadata.counter) = 1;
*(arc.get = &rep->value) = val;
return arc;
}
STC_INLINE Self _c_MEMB(_from)(_m_raw raw)
{ return _c_MEMB(_make)(i_keyfrom(raw)); }

STC_INLINE _m_raw _c_MEMB(_toraw)(const Self* self)
{ return i_keytoraw(self->get); }

STC_INLINE Self _c_MEMB(_move)(Self* self) {
Self arc = *self;
self->get = NULL, self->use_count = NULL;
return arc;
}

// destructor
STC_INLINE void _c_MEMB(_drop)(const Self* self) {
if (self->use_count && _i_atomic_dec_and_test(self->use_count)) {
enum {OFFSET = offsetof(struct _c_MEMB(_rep_), value)};
Expand All @@ -153,30 +152,37 @@ STC_INLINE void _c_MEMB(_drop)(const Self* self) {
}
}

// move ownership to receiving arc
STC_INLINE Self _c_MEMB(_move)(Self* self) {
Self arc = *self;
self->get = NULL, self->use_count = NULL;
return arc; // now unowned
}

// take ownership of pointer p
STC_INLINE void _c_MEMB(_reset_to)(Self* self, _m_value* ptr) {
_c_MEMB(_drop)(self);
*self = _c_MEMB(_from_ptr)(ptr);
}

STC_INLINE Self _c_MEMB(_from)(_m_raw raw)
{ return _c_MEMB(_make)(i_keyfrom(raw)); }

// does not use i_keyclone, so OK to always define.
STC_INLINE Self _c_MEMB(_clone)(Self arc) {
if (arc.use_count) _i_atomic_inc(arc.use_count);
return arc;
}

// take ownership of unowned
// take ownership of unowned arc
STC_INLINE void _c_MEMB(_take)(Self* self, Self unowned) {
c_assert(self->get != unowned.get);
_c_MEMB(_drop)(self);
*self = unowned;
}
// share ownership with arc
STC_INLINE void _c_MEMB(_assign)(Self* self, Self arc) {
if (arc.use_count) _i_atomic_inc(arc.use_count);

// make shared ownership with owned arc
STC_INLINE void _c_MEMB(_assign)(Self* self, const Self* owned) {
if (owned->use_count) _i_atomic_inc(owned->use_count);
_c_MEMB(_drop)(self);
*self = arc;
*self = *owned;
}

// clone by sharing. Does not use i_keyclone, so OK to always define.
STC_INLINE Self _c_MEMB(_clone)(Self owned) {
if (owned.use_count) _i_atomic_inc(owned.use_count);
return owned;
}

#if defined _i_has_cmp
Expand Down
41 changes: 23 additions & 18 deletions include/stc/box.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,6 @@ STC_INLINE Self _c_MEMB(_init)(void)
STC_INLINE long _c_MEMB(_use_count)(const Self* self)
{ return (long)(self->get != NULL); }

STC_INLINE Self _c_MEMB(_from_ptr)(_m_value* p)
{ return c_literal(Self){p}; }

// c++: std::make_unique<i_key>(val)
STC_INLINE Self _c_MEMB(_make)(_m_value val) {
Expand All @@ -94,6 +92,12 @@ STC_INLINE Self _c_MEMB(_make)(_m_value val) {
return box;
}

STC_INLINE Self _c_MEMB(_from_ptr)(_m_value* p)
{ return c_literal(Self){p}; }

STC_INLINE Self _c_MEMB(_from)(_m_raw raw)
{ return _c_MEMB(_make)(i_keyfrom(raw)); }

STC_INLINE _m_raw _c_MEMB(_toraw)(const Self* self)
{ return i_keytoraw(self->get); }

Expand All @@ -105,23 +109,37 @@ STC_INLINE void _c_MEMB(_drop)(const Self* self) {
}
}

// move ownership to receiving box
STC_INLINE Self _c_MEMB(_move)(Self* self) {
Self box = *self;
self->get = NULL;
return box;
}

// release owned pointer, must be manually freed by receiver
STC_INLINE _m_value* _c_MEMB(_release)(Self* self)
{ return _c_MEMB(_move)(self).get; }

// take ownership of p
// take ownership of pointer p
STC_INLINE void _c_MEMB(_reset_to)(Self* self, _m_value* p) {
_c_MEMB(_drop)(self);
self->get = p;
}

STC_INLINE Self _c_MEMB(_from)(_m_raw raw)
{ return _c_MEMB(_make)(i_keyfrom(raw)); }
// take ownership of unowned box
STC_INLINE void _c_MEMB(_take)(Self* self, Self unowned) {
_c_MEMB(_drop)(self);
*self = unowned;
}

// transfer ownership from other; set other to NULL
STC_INLINE void _c_MEMB(_assign)(Self* self, Self* owned) {
if (owned->get == self->get)
return;
_c_MEMB(_drop)(self);
*self = *owned;
owned->get = NULL;
}

#if !defined i_no_clone
STC_INLINE Self _c_MEMB(_clone)(Self other) {
Expand All @@ -132,19 +150,6 @@ STC_INLINE Self _c_MEMB(_from)(_m_raw raw)
}
#endif // !i_no_clone

// take ownership of unowned
STC_INLINE void _c_MEMB(_take)(Self* self, Self unowned) {
_c_MEMB(_drop)(self);
*self = unowned;
}
// transfer ownership from moved; set moved to NULL
STC_INLINE void _c_MEMB(_assign)(Self* self, Self* moved) {
if (moved->get == self->get)
return;
_c_MEMB(_drop)(self);
*self = *moved;
moved->get = NULL;
}

#if defined _i_has_cmp
STC_INLINE int _c_MEMB(_raw_cmp)(const _m_raw* rx, const _m_raw* ry)
Expand Down
2 changes: 1 addition & 1 deletion include/stc/cbits.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ STC_INLINE void cbits_set_pattern(cbits *self, const uintptr_t pattern);

STC_INLINE cbits cbits_move(cbits* self) {
cbits tmp = *self;
self->buffer = NULL, self->_size = 0;
memset(self, 0, sizeof *self);
return tmp;
}

Expand Down
9 changes: 4 additions & 5 deletions include/stc/priv/cstr_prv.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,11 @@ extern char* _cstr_internal_move(cstr* self, isize pos1, isize pos2);

#define cstr_init() (c_literal(cstr){0})
#define cstr_lit(literal) cstr_with_n(literal, c_litstrlen(literal))
#define cstr_join(sep, ...) \
cstr_join_array(sep, c_make_array(const char*, {__VA_ARGS__}), \
c_NUMARGS(__VA_ARGS__))
#define cstr_join_vec(sep, vecp) \
cstr_join_array_s(sep, (vecp)->data, (vecp)->size)
#define cstr_join_s(sep, ...) \
cstr_join_array_s(sep, c_make_array(cstr, {__VA_ARGS__}), \
c_NUMARGS(__VA_ARGS__))
cstr_join_array_s(sep, c_make_array(cstr, __VA_ARGS__), c_NUMARGS(__VA_ARGS__))

extern cstr cstr_from_replace(csview sv, csview search, csview repl, int32_t count);
extern cstr cstr_from_fmt(const char* fmt, ...);

Expand Down
14 changes: 7 additions & 7 deletions misc/tests/vec_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ TEST(vec, basics) {
c_forrange32 (i, 2, 9)
IVec_push_back(&d, i*10);

IVec res1 = c_init(IVec, {6, 7, 8, 9, 10, 11, 12, 20, 30, 40, 50, 60, 70, 80});
EXPECT_TRUE(IVec_eq(&res1, &d));
IVec res = c_init(IVec, {6, 7, 8, 9, 10, 11, 12, 20, 30, 40, 50, 60, 70, 80});
EXPECT_TRUE(IVec_eq(&res, &d));
EXPECT_EQ(14, IVec_size(&d));

IVec_erase_n(&d, 7, 4);

IVec res2 = c_init(IVec, {6, 7, 8, 9, 10, 11, 12, 60, 70, 80});
EXPECT_TRUE(IVec_eq(&res2, &d));
IVec_take(&res, c_init(IVec, {6, 7, 8, 9, 10, 11, 12, 60, 70, 80}));
EXPECT_TRUE(IVec_eq(&res, &d));

int nums[] = {200, 300, 400, 500};
IVec_insert_n(&d, 7, nums, 4);

IVec res3 = c_init(IVec, {6, 7, 8, 9, 10, 11, 12, 200, 300, 400, 500, 60, 70, 80});
EXPECT_TRUE(IVec_eq(&res3, &d));
IVec_take(&res, c_init(IVec, {6, 7, 8, 9, 10, 11, 12, 200, 300, 400, 500, 60, 70, 80}));
EXPECT_TRUE(IVec_eq(&res, &d));

EXPECT_EQ(14, IVec_size(&d));
EXPECT_EQ(200, *IVec_at(&d, 7));

c_drop(IVec, &d, &res1, &res2, &res3);
c_drop(IVec, &d, &res);
}

0 comments on commit 4e7cec6

Please sign in to comment.