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

Update TinySTL (attempt 2). #341

Merged
merged 1 commit into from
Jan 30, 2025
Merged
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
2 changes: 1 addition & 1 deletion include/tinystl/LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
Copyright 2012 Matthew Endsley
Copyright 2012-2018 Matthew Endsley
All rights reserved

Redistribution and use in source and binary forms, with or without
9 changes: 4 additions & 5 deletions include/tinystl/allocator.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright 2012 Matthew Endsley
* Copyright 2012-2018 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
@@ -27,9 +27,7 @@
#ifndef TINYSTL_ALLOCATOR_H
#define TINYSTL_ALLOCATOR_H

#include "stddef.h"

#ifndef TINYSTL_ALLOCATOR
#include <tinystl/stddef.h>

namespace tinystl {

@@ -44,7 +42,8 @@ namespace tinystl {
};
}

#ifndef TINYSTL_ALLOCATOR
# define TINYSTL_ALLOCATOR ::tinystl::allocator
#endif // TINYSTL_ALLOCATOR
#endif

#endif
79 changes: 51 additions & 28 deletions include/tinystl/buffer.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright 2012-1015 Matthew Endsley
* Copyright 2012-2018 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
@@ -27,8 +27,9 @@
#ifndef TINYSTL_BUFFER_H
#define TINYSTL_BUFFER_H

#include "new.h"
#include "traits.h"
#include <tinystl/allocator.h>
#include <tinystl/new.h>
#include <tinystl/traits.h>

namespace tinystl {

@@ -140,7 +141,7 @@ namespace tinystl {

template<typename T, typename Alloc>
static inline void buffer_reserve(buffer<T, Alloc>* b, size_t capacity) {
if (b->first + capacity <= b->capacity)
if (b->first && b->first + capacity <= b->capacity)
return;

typedef T* pointer;
@@ -174,19 +175,21 @@ namespace tinystl {

template<typename T, typename Alloc>
static inline void buffer_shrink_to_fit(buffer<T, Alloc>* b) {
if (b->last == b->first) {
const size_t capacity = (size_t)(b->last - b->first);
Alloc::static_deallocate(b->first, sizeof(T)*capacity);
b->capacity = b->first;
} else if (b->capacity != b->last) {
const size_t capacity = (size_t)(b->capacity - b->first);
const size_t size = (size_t)(b->last - b->first);
T* newfirst = (T*)Alloc::static_allocate(sizeof(T) * size);
buffer_move_urange(newfirst, b->first, b->last);
Alloc::static_deallocate(b->first, sizeof(T) * capacity);
b->first = newfirst;
b->last = newfirst + size;
b->capacity = b->last;
if (b->capacity != b->last) {
if (b->last == b->first) {
const size_t capacity = (size_t)(b->capacity - b->first);
Alloc::static_deallocate(b->first, sizeof(T)*capacity);
b->capacity = b->first = b->last = nullptr;
} else {
const size_t capacity = (size_t)(b->capacity - b->first);
const size_t size = (size_t)(b->last - b->first);
T* newfirst = (T*)Alloc::static_allocate(sizeof(T) * size);
buffer_move_urange(newfirst, b->first, b->last);
Alloc::static_deallocate(b->first, sizeof(T) * capacity);
b->first = newfirst;
b->last = newfirst + size;
b->capacity = b->last;
}
}
}

@@ -200,7 +203,7 @@ namespace tinystl {
static inline T* buffer_insert_common(buffer<T, Alloc>* b, T* where, size_t count) {
const size_t offset = (size_t)(where - b->first);
const size_t newsize = (size_t)((b->last - b->first) + count);
if (b->first + newsize > b->capacity)
if (!b->first || b->first + newsize > b->capacity)
buffer_reserve(b, (newsize * 3) / 2);

where = b->first + offset;
@@ -215,15 +218,29 @@ namespace tinystl {

template<typename T, typename Alloc, typename Param>
static inline void buffer_insert(buffer<T, Alloc>* b, T* where, const Param* first, const Param* last) {
where = buffer_insert_common(b, where, last - first);
typedef const char* pointer;
const size_t count = last - first;
const bool frombuf = ((pointer)b->first <= (pointer)first && (pointer)b->last >= (pointer)last);
size_t offset;
if (frombuf) {
offset = (pointer)first - (pointer)b->first;
if ((pointer)where <= (pointer)first)
offset += count * sizeof(T);
where = buffer_insert_common(b, where, count);
first = (Param*)((pointer)b->first + offset);
last = first + count;
}
else {
where = buffer_insert_common(b, where, count);
}
for (; first != last; ++first, ++where)
new(placeholder(), where) T(*first);
}

template<typename T, typename Alloc>
static inline void buffer_insert(buffer<T, Alloc>* b, T* where, size_t count) {
where = buffer_insert_common(b, where, count);
for (size_t i = 0; i < count; ++i)
for (T* end = where+count; where != end; ++where)
new(placeholder(), where) T();
}

@@ -250,28 +267,28 @@ namespace tinystl {
template<typename T, typename Alloc>
static inline T* buffer_erase(buffer<T, Alloc>* b, T* first, T* last) {
typedef T* pointer;
const size_t range = (last - first);
const size_t count = (last - first);
for (pointer it = last, end = b->last, dest = first; it != end; ++it, ++dest)
move(*dest, *it);

buffer_destroy_range(b->last - range, b->last);
buffer_destroy_range(b->last - count, b->last);

b->last -= range;
b->last -= count;
return first;
}

template<typename T, typename Alloc>
static inline T* buffer_erase_unordered(buffer<T, Alloc>* b, T* first, T* last) {
typedef T* pointer;
const size_t range = (last - first);
const size_t count = (last - first);
const size_t tail = (b->last - last);
pointer it = b->last - ((range < tail) ? range : tail);
pointer it = b->last - ((count < tail) ? count : tail);
for (pointer end = b->last, dest = first; it != end; ++it, ++dest)
move(*dest, *it);

buffer_destroy_range(b->last - range, b->last);
buffer_destroy_range(b->last - count, b->last);

b->last -= range;
b->last -= count;
return first;
}

@@ -282,6 +299,12 @@ namespace tinystl {
b->first = other->first, b->last = other->last, b->capacity = other->capacity;
other->first = tfirst, other->last = tlast, other->capacity = tcapacity;
}

template<typename T, typename Alloc>
static inline void buffer_move(buffer<T, Alloc>* dst, buffer<T, Alloc>* src) {
dst->first = src->first, dst->last = src->last, dst->capacity = src->capacity;
src->first = src->last = src->capacity = nullptr;
}
}

#endif
#endif //TINYSTL_BUFFER_H
4 changes: 2 additions & 2 deletions include/tinystl/hash.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright 2012 Matthew Endsley
* Copyright 2012-2018 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
#ifndef TINYSTL_STRINGHASH_H
#define TINYSTL_STRINGHASH_H

#include "stddef.h"
#include <tinystl/stddef.h>

namespace tinystl {

94 changes: 75 additions & 19 deletions include/tinystl/hash_base.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright 2012 Matthew Endsley
* Copyright 2012-2018 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
@@ -27,79 +27,134 @@
#ifndef TINYSTL_HASH_BASE_H
#define TINYSTL_HASH_BASE_H

#include "stddef.h"
#include <tinystl/stddef.h>
#include <tinystl/traits.h>

namespace tinystl {

template<typename Key, typename Value>
struct pair {
typedef Key first_type;
typedef Value second_type;

pair();
pair(const pair& other);
pair(pair&& other);
pair(const Key& key, const Value& value);
pair(Key&& key, Value&& value);

pair& operator=(const pair& other);
pair& operator=(pair&& other);

Key first;
Value second;

using first_type = Key;
using second_type = Value;
};

template<typename Key, typename Value>
pair<Key, Value>::pair() {
inline pair<Key, Value>::pair() {
}

template<typename Key, typename Value>
inline pair<Key, Value>::pair(const pair& other)
: first(other.first)
, second(other.second)
{
}

template<typename Key, typename Value>
inline pair<Key, Value>::pair(pair&& other)
: first(static_cast<Key&&>(other.first))
, second(static_cast<Value&&>(other.second))
{
}

template<typename Key, typename Value>
pair<Key, Value>::pair(const Key& key, const Value& value)
inline pair<Key, Value>::pair(const Key& key, const Value& value)
: first(key)
, second(value)
{
}

template<typename Key, typename Value>
static inline pair<Key, Value> make_pair(const Key& key, const Value& value) {
return pair<Key, Value>(key, value);
inline pair<Key, Value>::pair(Key&& key, Value&& value)
: first(static_cast<Key&&>(key))
, second(static_cast<Value&&>(value))
{
}

template<typename Key, typename Value>
inline pair<Key, Value>& pair<Key, Value>::operator=(const pair& other) {
first = other.first;
second = other.second;
return *this;
}

template<typename Key, typename Value>
inline pair<Key, Value>& pair<Key, Value>::operator=(pair&& other) {
first = static_cast<Key&&>(other.first);
second = static_cast<Value&&>(other.second);
return *this;
}

template<typename Key, typename Value>
static inline pair<typename remove_const_reference<Key>::type, typename remove_const_reference<Value>::type>
make_pair(Key&& key, Value&& value) {
return pair<typename remove_const_reference<Key>::type, typename remove_const_reference<Value>::type>(
static_cast<Key&&>(key)
, static_cast<Value&&>(value)
);
}


template<typename Key, typename Value>
struct unordered_hash_node {
unordered_hash_node(const Key& key, const Value& value);
unordered_hash_node(Key&& key, Value&& value);

const Key first;
Value second;
unordered_hash_node* next;
unordered_hash_node* prev;

private:
unordered_hash_node& operator=(const unordered_hash_node&);
};

template<typename Key, typename Value>
unordered_hash_node<Key, Value>::unordered_hash_node(const Key& key, const Value& value)
inline unordered_hash_node<Key, Value>::unordered_hash_node(const Key& key, const Value& value)
: first(key)
, second(value)
{
}

template<typename Key, typename Value>
inline unordered_hash_node<Key, Value>::unordered_hash_node(Key&& key, Value&& value)
: first(static_cast<Key&&>(key))
, second(static_cast<Value&&>(value))
{
}

template <typename Key>
struct unordered_hash_node<Key, void> {
unordered_hash_node(const Key& key);
explicit unordered_hash_node(const Key& key);
explicit unordered_hash_node(Key&& key);

const Key first;
unordered_hash_node* next;
unordered_hash_node* prev;

private:
unordered_hash_node& operator=(const unordered_hash_node&);
};

template<typename Key>
unordered_hash_node<Key, void>::unordered_hash_node(const Key& key)
inline unordered_hash_node<Key, void>::unordered_hash_node(const Key& key)
: first(key)
{
}

template<typename Key>
inline unordered_hash_node<Key, void>::unordered_hash_node(Key&& key)
: first(static_cast<Key&&>(key))
{
}

template<typename Key, typename Value>
static void unordered_hash_node_insert(unordered_hash_node<Key, Value>* node, size_t hash, unordered_hash_node<Key, Value>** buckets, size_t nbuckets) {
static inline void unordered_hash_node_insert(unordered_hash_node<Key, Value>* node, size_t hash, unordered_hash_node<Key, Value>** buckets, size_t nbuckets) {
size_t bucket = hash & (nbuckets - 1);

unordered_hash_node<Key, Value>* it = buckets[bucket + 1];
@@ -223,6 +278,7 @@ namespace tinystl {

template<typename Node, typename Key>
static inline Node unordered_hash_find(const Key& key, Node* buckets, size_t nbuckets) {
if (!buckets) return 0;
const size_t bucket = hash(key) & (nbuckets - 2);
for (Node it = buckets[bucket], end = buckets[bucket+1]; it != end; it = it->next)
if (it->first == key)
4 changes: 2 additions & 2 deletions include/tinystl/new.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*-
* Copyright 2012 Matthew Endsley
* Copyright 2012-2018 Matthew Endsley
* All rights reserved
*
* Redistribution and use in source and binary forms, with or without
@@ -27,7 +27,7 @@
#ifndef TINYSTL_NEW_H
#define TINYSTL_NEW_H

#include "stddef.h"
#include <tinystl/stddef.h>

namespace tinystl {

Loading