Skip to content

Commit

Permalink
TinySTL attempt 3. (#342)
Browse files Browse the repository at this point in the history
* Update TinySTL (attempt 2).

* Fix MSVC compilation issue for TinySTL.

* Fix MSVC warning.

* Favor ptrdiff_t for sizes in string.

* Update genie.lua

* Update math_test.cpp

* Update test.h

* Update test.h

---------

Co-authored-by: Бранимир Караџић <branimirkaradzic@gmail.com>
  • Loading branch information
mcourteaux and bkaradzic authored Feb 1, 2025
1 parent fae06fa commit 5fb8c15
Show file tree
Hide file tree
Showing 20 changed files with 1,229 additions and 270 deletions.
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
Expand Down
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
Expand Down Expand Up @@ -27,9 +27,7 @@
#ifndef TINYSTL_ALLOCATOR_H
#define TINYSTL_ALLOCATOR_H

#include "stddef.h"

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

namespace tinystl {

Expand All @@ -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
Expand Down Expand Up @@ -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 {

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}
}
}

Expand All @@ -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;
Expand All @@ -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();
}

Expand All @@ -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;
}

Expand All @@ -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
Expand Down Expand Up @@ -27,7 +27,7 @@
#ifndef TINYSTL_STRINGHASH_H
#define TINYSTL_STRINGHASH_H

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

namespace tinystl {

Expand Down
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
Expand Down Expand Up @@ -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];
Expand Down Expand Up @@ -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)
Expand Down
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
Expand Down Expand Up @@ -27,7 +27,7 @@
#ifndef TINYSTL_NEW_H
#define TINYSTL_NEW_H

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

namespace tinystl {

Expand Down
Loading

0 comments on commit 5fb8c15

Please sign in to comment.