mirror of
https://github.com/bkaradzic/bx.git
synced 2026-02-17 20:52:37 +01:00
Added tinystl.
This commit is contained in:
23
include/tinystl/LICENSE
Normal file
23
include/tinystl/LICENSE
Normal file
@@ -0,0 +1,23 @@
|
||||
Copyright 2012 Matthew Endsley
|
||||
All rights reserved
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted providing that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
49
include/tinystl/allocator.h
Normal file
49
include/tinystl/allocator.h
Normal file
@@ -0,0 +1,49 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_ALLOCATOR_H
|
||||
#define TINYSTL_ALLOCATOR_H
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
struct allocator {
|
||||
static void* static_allocate(size_t bytes) {
|
||||
return operator new(bytes);
|
||||
}
|
||||
|
||||
static void static_deallocate(void* ptr, size_t /*bytes*/) {
|
||||
operator delete(ptr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#ifndef TINYSTL_ALLOCATOR
|
||||
# define TINYSTL_ALLOCATOR ::tinystl::allocator
|
||||
#endif
|
||||
|
||||
#endif
|
||||
212
include/tinystl/buffer.h
Normal file
212
include/tinystl/buffer.h
Normal file
@@ -0,0 +1,212 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_BUFFER_H
|
||||
#define TINYSTL_BUFFER_H
|
||||
|
||||
#include "allocator.h"
|
||||
#include "new.h"
|
||||
#include "traits.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
template<typename T, typename Alloc = TINYSTL_ALLOCATOR>
|
||||
struct buffer {
|
||||
T* first;
|
||||
T* last;
|
||||
T* capacity;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_destroy_range_traits(T* first, T* last, pod_traits<T, false>) {
|
||||
for (; first < last; ++first)
|
||||
first->~T();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_destroy_range_traits(T*, T*, pod_traits<T, true>) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_destroy_range(T* first, T* last) {
|
||||
buffer_destroy_range_traits(first, last, pod_traits<T>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_fill_urange_traits(T* first, T* last, const T& value, pod_traits<T, false>) {
|
||||
for (; first < last; ++first)
|
||||
new(placeholder(), first) T(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_fill_urange_traits(T* first, T* last, const T& value, pod_traits<T, true>) {
|
||||
for (; first < last; ++first)
|
||||
*first = value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_move_urange_traits(T* dest, T* first, T* last, pod_traits<T, false>) {
|
||||
for (T* it = first; it != last; ++it, ++dest)
|
||||
move_construct(dest, *it);
|
||||
buffer_destroy_range(first, last);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_move_urange_traits(T* dest, T* first, T* last, pod_traits<T, true>) {
|
||||
for (; first != last; ++first, ++dest)
|
||||
*dest = *first;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_bmove_urange_traits(T* dest, T* first, T* last, pod_traits<T, false>) {
|
||||
dest += (last - first);
|
||||
for (T* it = last; it != first; --it, --dest) {
|
||||
move_construct(dest - 1, *(it - 1));
|
||||
buffer_destroy_range(it - 1, it);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_bmove_urange_traits(T* dest, T* first, T* last, pod_traits<T, true>) {
|
||||
dest += (last - first);
|
||||
for (T* it = last; it != first; --it, --dest)
|
||||
*(dest - 1) = *(it - 1);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_move_urange(T* dest, T* first, T* last) {
|
||||
buffer_move_urange_traits(dest, first, last, pod_traits<T>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_bmove_urange(T* dest, T* first, T* last) {
|
||||
buffer_bmove_urange_traits(dest, first, last, pod_traits<T>());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void buffer_fill_urange(T* first, T* last, const T& value) {
|
||||
buffer_fill_urange_traits(first, last, value, pod_traits<T>());
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static inline void buffer_init(buffer<T, Alloc>* b) {
|
||||
b->first = b->last = b->capacity = 0;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static inline void buffer_destroy(buffer<T, Alloc>* b) {
|
||||
buffer_destroy_range(b->first, b->last);
|
||||
Alloc::static_deallocate(b->first, (size_t)((char*)b->first - (char*)b->last));
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static inline void buffer_reserve(buffer<T, Alloc>* b, size_t capacity) {
|
||||
if (b->first + capacity <= b->capacity)
|
||||
return;
|
||||
|
||||
typedef T* pointer;
|
||||
const size_t size = (size_t)(b->last - b->first);
|
||||
pointer newfirst = (pointer)Alloc::static_allocate(sizeof(T) * capacity);
|
||||
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 = newfirst + capacity;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static inline void buffer_resize(buffer<T, Alloc>* b, size_t size, const T& value) {
|
||||
buffer_reserve(b, size);
|
||||
|
||||
buffer_fill_urange(b->last, b->first + size, value);
|
||||
buffer_destroy_range(b->first + size, b->last);
|
||||
b->last = b->first + size;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static inline void buffer_clear(buffer<T, Alloc>* b) {
|
||||
buffer_destroy_range(b->first, b->last);
|
||||
b->last = b->first;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static inline void buffer_insert(buffer<T, Alloc>* b, T* where, const T* first, const T* last) {
|
||||
const size_t offset = (size_t)(where - b->first);
|
||||
const size_t newsize = (size_t)((b->last - b->first) + (last - first));
|
||||
if (b->first + newsize > b->capacity)
|
||||
buffer_reserve(b, (newsize * 3) / 2);
|
||||
|
||||
where = b->first + offset;
|
||||
const size_t count = (size_t)(last - first);
|
||||
|
||||
if (where != b->last)
|
||||
buffer_bmove_urange(where + count, where, b->last);
|
||||
|
||||
for (; first != last; ++first, ++where)
|
||||
new(placeholder(), where) T(*first);
|
||||
|
||||
b->last = b->first + newsize;
|
||||
}
|
||||
|
||||
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);
|
||||
for (pointer it = last, end = b->last, dest = first; it != end; ++it, ++dest)
|
||||
move(*dest, *it);
|
||||
|
||||
buffer_destroy_range(b->last - range, b->last);
|
||||
|
||||
b->last -= range;
|
||||
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 tail = (b->last - last);
|
||||
pointer it = b->last - ((range < tail) ? range : tail);
|
||||
for (pointer end = b->last, dest = first; it != end; ++it, ++dest)
|
||||
move(*dest, *it);
|
||||
|
||||
buffer_destroy_range(b->last - range, b->last);
|
||||
|
||||
b->last -= range;
|
||||
return first;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
static inline void buffer_swap(buffer<T, Alloc>* b, buffer<T, Alloc>* other) {
|
||||
typedef T* pointer;
|
||||
const pointer tfirst = b->first, tlast = b->last, tcapacity = b->capacity;
|
||||
b->first = other->first, b->last = other->last, b->capacity = other->capacity;
|
||||
other->first = tfirst, other->last = tlast, other->capacity = tcapacity;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
53
include/tinystl/hash.h
Normal file
53
include/tinystl/hash.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_STRINGHASH_H
|
||||
#define TINYSTL_STRINGHASH_H
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
static inline size_t hash_string(const char* str, size_t len) {
|
||||
// Implementation of sdbm a public domain string hash from Ozan Yigit
|
||||
// see: http://www.eecs.harvard.edu/margo/papers/usenix91/paper.ps
|
||||
|
||||
size_t hash = 0;
|
||||
typedef const char* pointer;
|
||||
for (pointer it = str, end = str + len; it != end; ++it)
|
||||
hash = *it + (hash << 6) + (hash << 16) - hash;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline size_t hash(const T& value) {
|
||||
const size_t asint = (size_t)value;
|
||||
return hash_string((const char*)&asint, sizeof(asint));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
225
include/tinystl/hash_base.h
Normal file
225
include/tinystl/hash_base.h
Normal file
@@ -0,0 +1,225 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_HASH_BASE_H
|
||||
#define TINYSTL_HASH_BASE_H
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
template<typename Key, typename Value>
|
||||
struct pair {
|
||||
pair();
|
||||
pair(const Key& key, const Value& value);
|
||||
|
||||
Key first;
|
||||
Value second;
|
||||
};
|
||||
|
||||
template<typename Key, typename Value>
|
||||
pair<Key, Value>::pair() {
|
||||
}
|
||||
|
||||
template<typename Key, typename Value>
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
template<typename Key, typename Value>
|
||||
struct unordered_hash_node {
|
||||
unordered_hash_node(const Key& key, const Value& value);
|
||||
|
||||
const Key first;
|
||||
Value second;
|
||||
unordered_hash_node* next;
|
||||
unordered_hash_node* prev;
|
||||
};
|
||||
|
||||
template<typename Key, typename Value>
|
||||
unordered_hash_node<Key, Value>::unordered_hash_node(const Key& key, const Value& value)
|
||||
: first(key)
|
||||
, second(value)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename Key>
|
||||
struct unordered_hash_node<Key, void> {
|
||||
unordered_hash_node(const Key& key);
|
||||
|
||||
const Key first;
|
||||
unordered_hash_node* next;
|
||||
unordered_hash_node* prev;
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
unordered_hash_node<Key, void>::unordered_hash_node(const Key& key)
|
||||
: first(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) {
|
||||
size_t bucket = hash & (nbuckets - 1);
|
||||
|
||||
unordered_hash_node<Key, Value>* it = buckets[bucket + 1];
|
||||
node->next = it;
|
||||
if (it) {
|
||||
node->prev = it->prev;
|
||||
it->prev = node;
|
||||
if (node->prev)
|
||||
node->prev->next = node;
|
||||
} else {
|
||||
size_t newbucket = bucket;
|
||||
while (newbucket && !buckets[newbucket])
|
||||
--newbucket;
|
||||
|
||||
unordered_hash_node<Key, Value>* prev = buckets[newbucket];
|
||||
while (prev && prev->next)
|
||||
prev = prev->next;
|
||||
|
||||
node->prev = prev;
|
||||
if (prev)
|
||||
prev->next = node;
|
||||
}
|
||||
|
||||
// propagate node through buckets
|
||||
for (; it == buckets[bucket]; --bucket) {
|
||||
buckets[bucket] = node;
|
||||
if (!bucket)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Key, typename Value>
|
||||
static inline void unordered_hash_node_erase(const unordered_hash_node<Key, Value>* where, size_t hash, unordered_hash_node<Key, Value>** buckets, size_t nbuckets) {
|
||||
size_t bucket = hash & (nbuckets - 1);
|
||||
|
||||
unordered_hash_node<Key, Value>* next = where->next;
|
||||
for (; buckets[bucket] == where; --bucket) {
|
||||
buckets[bucket] = next;
|
||||
if (!bucket)
|
||||
break;
|
||||
}
|
||||
|
||||
if (where->prev)
|
||||
where->prev->next = where->next;
|
||||
if (next)
|
||||
next->prev = where->prev;
|
||||
}
|
||||
|
||||
template<typename Node>
|
||||
struct unordered_hash_iterator {
|
||||
Node* operator->() const;
|
||||
Node& operator*() const;
|
||||
Node* node;
|
||||
};
|
||||
|
||||
template<typename Node>
|
||||
struct unordered_hash_iterator<const Node> {
|
||||
|
||||
unordered_hash_iterator() {}
|
||||
unordered_hash_iterator(unordered_hash_iterator<Node> other)
|
||||
: node(other.node)
|
||||
{
|
||||
}
|
||||
|
||||
const Node* operator->() const;
|
||||
const Node& operator*() const;
|
||||
const Node* node;
|
||||
};
|
||||
|
||||
template<typename Key>
|
||||
struct unordered_hash_iterator<const unordered_hash_node<Key, void> > {
|
||||
const Key* operator->() const;
|
||||
const Key& operator*() const;
|
||||
unordered_hash_node<Key, void>* node;
|
||||
};
|
||||
|
||||
template<typename LNode, typename RNode>
|
||||
static inline bool operator==(const unordered_hash_iterator<LNode>& lhs, const unordered_hash_iterator<RNode>& rhs) {
|
||||
return lhs.node == rhs.node;
|
||||
}
|
||||
|
||||
template<typename LNode, typename RNode>
|
||||
static inline bool operator!=(const unordered_hash_iterator<LNode>& lhs, const unordered_hash_iterator<RNode>& rhs) {
|
||||
return lhs.node != rhs.node;
|
||||
}
|
||||
|
||||
template<typename Node>
|
||||
static inline void operator++(unordered_hash_iterator<Node>& lhs) {
|
||||
lhs.node = lhs.node->next;
|
||||
}
|
||||
|
||||
template<typename Node>
|
||||
inline Node* unordered_hash_iterator<Node>::operator->() const {
|
||||
return node;
|
||||
}
|
||||
|
||||
template<typename Node>
|
||||
inline Node& unordered_hash_iterator<Node>::operator*() const {
|
||||
return *node;
|
||||
}
|
||||
|
||||
template<typename Node>
|
||||
inline const Node* unordered_hash_iterator<const Node>::operator->() const {
|
||||
return node;
|
||||
}
|
||||
|
||||
template<typename Node>
|
||||
inline const Node& unordered_hash_iterator<const Node>::operator*() const {
|
||||
return *node;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
inline const Key* unordered_hash_iterator<const unordered_hash_node<Key, void> >::operator->() const {
|
||||
return &node->first;
|
||||
}
|
||||
|
||||
template<typename Key>
|
||||
inline const Key& unordered_hash_iterator<const unordered_hash_node<Key, void> >::operator*() const {
|
||||
return node->first;
|
||||
}
|
||||
|
||||
template<typename Node, typename Key>
|
||||
static inline Node unordered_hash_find(const Key& key, Node* buckets, size_t nbuckets) {
|
||||
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)
|
||||
return it;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
43
include/tinystl/new.h
Normal file
43
include/tinystl/new.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_NEW_H
|
||||
#define TINYSTL_NEW_H
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
struct placeholder {};
|
||||
}
|
||||
|
||||
inline void* operator new(size_t, tinystl::placeholder, void* ptr) {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
inline void operator delete(void*, tinystl::placeholder, void*) throw() {}
|
||||
|
||||
#endif
|
||||
40
include/tinystl/stddef.h
Normal file
40
include/tinystl/stddef.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_STDDEF_H
|
||||
#define TINYSTL_STDDEF_H
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef long long unsigned int size_t;
|
||||
#elif defined(_WIN32)
|
||||
typedef unsigned int size_t;
|
||||
#elif defined (__linux__) && defined(__SIZE_TYPE__)
|
||||
typedef __SIZE_TYPE__ size_t;
|
||||
#else
|
||||
# include <stddef.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
212
include/tinystl/string.h
Normal file
212
include/tinystl/string.h
Normal file
@@ -0,0 +1,212 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_STRING_H
|
||||
#define TINYSTL_STRING_H
|
||||
|
||||
#include "allocator.h"
|
||||
#include "stddef.h"
|
||||
#include "hash.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
class string {
|
||||
public:
|
||||
string();
|
||||
string(const string& other);
|
||||
string(const char* sz);
|
||||
string(const char* sz, size_t len);
|
||||
~string();
|
||||
|
||||
string& operator=(const string& other);
|
||||
|
||||
const char* c_str() const;
|
||||
size_t size() const;
|
||||
|
||||
void reserve(size_t size);
|
||||
void resize(size_t size);
|
||||
|
||||
void append(const char* first, const char* last);
|
||||
|
||||
void swap(string& other);
|
||||
|
||||
private:
|
||||
typedef char* pointer;
|
||||
pointer m_first;
|
||||
pointer m_last;
|
||||
pointer m_capacity;
|
||||
|
||||
static const size_t c_nbuffer = 12;
|
||||
char m_buffer[12];
|
||||
};
|
||||
|
||||
inline string::string()
|
||||
: m_first(m_buffer)
|
||||
, m_last(m_buffer)
|
||||
, m_capacity(m_buffer + c_nbuffer)
|
||||
{
|
||||
resize(0);
|
||||
}
|
||||
|
||||
inline string::string(const string& other)
|
||||
: m_first(m_buffer)
|
||||
, m_last(m_buffer)
|
||||
, m_capacity(m_buffer + c_nbuffer)
|
||||
{
|
||||
reserve(other.size());
|
||||
append(other.m_first, other.m_last);
|
||||
}
|
||||
|
||||
inline string::string(const char* sz)
|
||||
: m_first(m_buffer)
|
||||
, m_last(m_buffer)
|
||||
, m_capacity(m_buffer + c_nbuffer)
|
||||
{
|
||||
size_t len = 0;
|
||||
for (const char* it = sz; *it; ++it)
|
||||
++len;
|
||||
|
||||
reserve(len);
|
||||
append(sz, sz + len);
|
||||
}
|
||||
|
||||
inline string::string(const char* sz, size_t len)
|
||||
: m_first(m_buffer)
|
||||
, m_last(m_buffer)
|
||||
, m_capacity(m_buffer + c_nbuffer)
|
||||
{
|
||||
reserve(len);
|
||||
append(sz, sz + len);
|
||||
}
|
||||
|
||||
inline string::~string() {
|
||||
if (m_first != m_buffer)
|
||||
TINYSTL_ALLOCATOR::static_deallocate(m_first, m_capacity - m_first);
|
||||
}
|
||||
|
||||
inline string& string::operator=(const string& other) {
|
||||
string(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline const char* string::c_str() const {
|
||||
return m_first;
|
||||
}
|
||||
|
||||
inline size_t string::size() const
|
||||
{
|
||||
return (size_t)(m_last - m_first);
|
||||
}
|
||||
|
||||
inline void string::reserve(size_t capacity) {
|
||||
if (m_first + capacity + 1 <= m_capacity)
|
||||
return;
|
||||
|
||||
const size_t size = (size_t)(m_last - m_first);
|
||||
|
||||
pointer newfirst = (pointer)TINYSTL_ALLOCATOR::static_allocate(capacity + 1);
|
||||
for (pointer it = m_first, newit = newfirst, end = m_last; it != end; ++it, ++newit)
|
||||
*newit = *it;
|
||||
if (m_first != m_buffer)
|
||||
TINYSTL_ALLOCATOR::static_deallocate(m_first, m_capacity - m_first);
|
||||
|
||||
m_first = newfirst;
|
||||
m_last = newfirst + size;
|
||||
m_capacity = m_first + capacity;
|
||||
}
|
||||
|
||||
inline void string::resize(size_t size) {
|
||||
reserve(size);
|
||||
for (pointer it = m_last, end = m_first + size + 1; it < end; ++it)
|
||||
*it = 0;
|
||||
|
||||
m_last += size;
|
||||
}
|
||||
|
||||
inline void string::append(const char* first, const char* last) {
|
||||
const size_t newsize = (size_t)((m_last - m_first) + (last - first) + 1);
|
||||
if (m_first + newsize > m_capacity)
|
||||
reserve((newsize * 3) / 2);
|
||||
|
||||
for (; first != last; ++m_last, ++first)
|
||||
*m_last = *first;
|
||||
*m_last = 0;
|
||||
}
|
||||
|
||||
inline void string::swap(string& other) {
|
||||
const pointer tfirst = m_first, tlast = m_last, tcapacity = m_capacity;
|
||||
m_first = other.m_first, m_last = other.m_last, m_capacity = other.m_capacity;
|
||||
other.m_first = tfirst, other.m_last = tlast, other.m_capacity = tcapacity;
|
||||
|
||||
char tbuffer[c_nbuffer];
|
||||
|
||||
if (m_first == other.m_buffer)
|
||||
for (pointer it = other.m_buffer, end = m_last, out = tbuffer; it != end; ++it, ++out)
|
||||
*out = *it;
|
||||
|
||||
if (other.m_first == m_buffer) {
|
||||
other.m_last = other.m_last - other.m_first + other.m_buffer;
|
||||
other.m_first = other.m_buffer;
|
||||
other.m_capacity = other.m_buffer + c_nbuffer;
|
||||
|
||||
for (pointer it = other.m_first, end = other.m_last, in = m_buffer; it != end; ++it, ++in)
|
||||
*it = *in;
|
||||
*other.m_last = 0;
|
||||
}
|
||||
|
||||
if (m_first == other.m_buffer) {
|
||||
m_last = m_last - m_first + m_buffer;
|
||||
m_first = m_buffer;
|
||||
m_capacity = m_buffer + c_nbuffer;
|
||||
|
||||
for (pointer it = m_first, end = m_last, in = tbuffer; it != end; ++it, ++in)
|
||||
*it = *in;
|
||||
*m_last = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool operator==(const string& lhs, const string& rhs) {
|
||||
typedef const char* pointer;
|
||||
|
||||
const size_t lsize = lhs.size(), rsize = rhs.size();
|
||||
if (lsize != rsize)
|
||||
return false;
|
||||
|
||||
pointer lit = lhs.c_str(), rit = rhs.c_str();
|
||||
pointer lend = lit + lsize;
|
||||
while (lit != lend)
|
||||
if (*lit++ != *rit++)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline size_t hash(const string& value) {
|
||||
return hash_string(value.c_str(), value.size());
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
85
include/tinystl/traits.h
Normal file
85
include/tinystl/traits.h
Normal file
@@ -0,0 +1,85 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_TRAITS_H
|
||||
#define TINYSTL_TRAITS_H
|
||||
|
||||
#include "new.h"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
# define TINYSTL_TRY_POD_OPTIMIZATION(t) __is_pod(t)
|
||||
#elif defined(_MSC_VER)
|
||||
# define TINYSTL_TRY_POD_OPTIMIZATION(t) (!__is_class(t) || __is_pod(t))
|
||||
#else
|
||||
# define TINYSTL_TRY_POD_OPTIMIZATION(t) false
|
||||
#endif
|
||||
|
||||
namespace tinystl {
|
||||
template<typename T, bool pod = TINYSTL_TRY_POD_OPTIMIZATION(T)> struct pod_traits {};
|
||||
|
||||
template<typename T, T t> struct swap_holder;
|
||||
|
||||
template<typename T>
|
||||
static inline void move_impl(T& a, T& b, ...) {
|
||||
a = b;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void move_impl(T& a, T& b, T*, swap_holder<void (T::*)(T&), &T::swap>* = 0) {
|
||||
a.swap(b);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void move(T& a, T&b) {
|
||||
move_impl(a, b, (T*)0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void move_construct_impl(T* a, T& b, ...) {
|
||||
new(placeholder(), a) T(b);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void move_construct_impl(T* a, T& b, void*, swap_holder<void (T::*)(T&), &T::swap>* = 0) {
|
||||
// If your type T does not have a default constructor, simply insert:
|
||||
// struct tinystl_nomove_construct;
|
||||
// in the class definition
|
||||
new(placeholder(), a) T;
|
||||
a->swap(b);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void move_construct_impl(T* a, T& b, T*, typename T::tinystl_nomove_construct* = 0) {
|
||||
new(placeholder(), a) T(b);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static inline void move_construct(T* a, T& b) {
|
||||
move_construct_impl(a, b, (T*)0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
241
include/tinystl/unordered_map.h
Normal file
241
include/tinystl/unordered_map.h
Normal file
@@ -0,0 +1,241 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_UNORDERED_MAP_H
|
||||
#define TINYSTL_UNORDERED_MAP_H
|
||||
|
||||
#include "allocator.h"
|
||||
#include "buffer.h"
|
||||
#include "hash.h"
|
||||
#include "hash_base.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
template<typename Key, typename Value, typename Alloc = TINYSTL_ALLOCATOR>
|
||||
class unordered_map {
|
||||
public:
|
||||
unordered_map();
|
||||
unordered_map(const unordered_map& other);
|
||||
~unordered_map();
|
||||
|
||||
unordered_map& operator=(const unordered_map& other);
|
||||
|
||||
|
||||
typedef pair<Key, Value> value_type;
|
||||
|
||||
typedef unordered_hash_iterator<const unordered_hash_node<Key, Value> > const_iterator;
|
||||
typedef unordered_hash_iterator<unordered_hash_node<Key, Value> > iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
void clear();
|
||||
bool empty() const;
|
||||
size_t size() const;
|
||||
|
||||
const_iterator find(const Key& key) const;
|
||||
iterator find(const Key& key);
|
||||
pair<iterator, bool> insert(const pair<Key, Value>& p);
|
||||
void erase(const_iterator where);
|
||||
|
||||
Value& operator[](const Key& key);
|
||||
|
||||
void swap(unordered_map& other);
|
||||
|
||||
private:
|
||||
|
||||
typedef unordered_hash_node<Key, Value>* pointer;
|
||||
|
||||
size_t m_size;
|
||||
tinystl::buffer<pointer, Alloc> m_buckets;
|
||||
};
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
unordered_map<Key, Value, Alloc>::unordered_map()
|
||||
: m_size(0)
|
||||
{
|
||||
buffer_init<pointer, Alloc>(&m_buckets);
|
||||
buffer_resize<pointer, Alloc>(&m_buckets, 9, 0);
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
unordered_map<Key, Value, Alloc>::unordered_map(const unordered_map& other)
|
||||
: m_size(other.m_size)
|
||||
{
|
||||
const size_t nbuckets = (size_t)(other.m_buckets.last - other.m_buckets.first);
|
||||
buffer_init<pointer, Alloc>(&m_buckets);
|
||||
buffer_resize<pointer, Alloc>(&m_buckets, nbuckets, 0);
|
||||
|
||||
for (pointer it = *other.m_buckets.first; it; it = it->next) {
|
||||
unordered_hash_node<Key, Value>* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node<Key, Value>))) unordered_hash_node<Key, Value>(it->first, it->second);
|
||||
newnode->next = newnode->prev = 0;
|
||||
|
||||
unordered_hash_node_insert(newnode, hash(it->first), m_buckets.first, nbuckets - 1);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
unordered_map<Key, Value, Alloc>::~unordered_map() {
|
||||
clear();
|
||||
buffer_destroy<pointer, Alloc>(&m_buckets);
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
unordered_map<Key, Value, Alloc>& unordered_map<Key, Value, Alloc>::operator=(const unordered_map<Key, Value, Alloc>& other) {
|
||||
unordered_map<Key, Value, Alloc>(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline typename unordered_map<Key, Value, Alloc>::iterator unordered_map<Key, Value, Alloc>::begin() {
|
||||
iterator it;
|
||||
it.node = *m_buckets.first;
|
||||
return it;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline typename unordered_map<Key, Value, Alloc>::iterator unordered_map<Key, Value, Alloc>::end() {
|
||||
iterator it;
|
||||
it.node = 0;
|
||||
return it;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline typename unordered_map<Key, Value, Alloc>::const_iterator unordered_map<Key, Value, Alloc>::begin() const {
|
||||
const_iterator cit;
|
||||
cit.node = *m_buckets.first;
|
||||
return cit;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline typename unordered_map<Key, Value, Alloc>::const_iterator unordered_map<Key, Value, Alloc>::end() const {
|
||||
const_iterator cit;
|
||||
cit.node = 0;
|
||||
return cit;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline bool unordered_map<Key, Value, Alloc>::empty() const {
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline size_t unordered_map<Key, Value, Alloc>::size() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline void unordered_map<Key, Value, Alloc>::clear() {
|
||||
pointer it = *m_buckets.first;
|
||||
while (it) {
|
||||
const pointer next = it->next;
|
||||
it->~unordered_hash_node<Key, Value>();
|
||||
Alloc::static_deallocate(it, sizeof(unordered_hash_node<Key, Value>));
|
||||
|
||||
it = next;
|
||||
}
|
||||
|
||||
m_buckets.last = m_buckets.first;
|
||||
buffer_resize<pointer, Alloc>(&m_buckets, 9, 0);
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline typename unordered_map<Key, Value, Alloc>::iterator unordered_map<Key, Value, Alloc>::find(const Key& key) {
|
||||
iterator result;
|
||||
result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline typename unordered_map<Key, Value, Alloc>::const_iterator unordered_map<Key, Value, Alloc>::find(const Key& key) const {
|
||||
iterator result;
|
||||
result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
inline pair<typename unordered_map<Key, Value, Alloc>::iterator, bool> unordered_map<Key, Value, Alloc>::insert(const pair<Key, Value>& p) {
|
||||
pair<iterator, bool> result;
|
||||
result.second = false;
|
||||
|
||||
result.first = find(p.first);
|
||||
if (result.first.node != 0)
|
||||
return result;
|
||||
|
||||
unordered_hash_node<Key, Value>* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node<Key, Value>))) unordered_hash_node<Key, Value>(p.first, p.second);
|
||||
newnode->next = newnode->prev = 0;
|
||||
|
||||
const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first);
|
||||
unordered_hash_node_insert(newnode, hash(p.first), m_buckets.first, nbuckets - 1);
|
||||
|
||||
++m_size;
|
||||
if (m_size + 1 > 4 * nbuckets) {
|
||||
pointer root = *m_buckets.first;
|
||||
|
||||
const size_t newnbuckets = ((size_t)(m_buckets.last - m_buckets.first) - 1) * 8;
|
||||
m_buckets.last = m_buckets.first;
|
||||
buffer_resize<pointer, Alloc>(&m_buckets, newnbuckets + 1, 0);
|
||||
unordered_hash_node<Key, Value>** buckets = m_buckets.first;
|
||||
|
||||
while (root) {
|
||||
const pointer next = root->next;
|
||||
root->next = root->prev = 0;
|
||||
unordered_hash_node_insert(root, hash(root->first), buckets, newnbuckets);
|
||||
root = next;
|
||||
}
|
||||
}
|
||||
|
||||
result.first.node = newnode;
|
||||
result.second = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
void unordered_map<Key, Value, Alloc>::erase(const_iterator where) {
|
||||
unordered_hash_node_erase(where.node, hash(where->first), m_buckets.first, (size_t)(m_buckets.last - m_buckets.first) - 1);
|
||||
|
||||
where->~unordered_hash_node<Key, Value>();
|
||||
Alloc::static_deallocate((void*)where.node, sizeof(unordered_hash_node<Key, Value>));
|
||||
--m_size;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
Value& unordered_map<Key, Value, Alloc>::operator[](const Key& key) {
|
||||
return insert(pair<Key, Value>(key, Value())).first->second;
|
||||
}
|
||||
|
||||
template<typename Key, typename Value, typename Alloc>
|
||||
void unordered_map<Key, Value, Alloc>::swap(unordered_map& other) {
|
||||
size_t tsize = other.m_size;
|
||||
other.m_size = m_size, m_size = tsize;
|
||||
buffer_swap(&m_buckets, &other.m_buckets);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
216
include/tinystl/unordered_set.h
Normal file
216
include/tinystl/unordered_set.h
Normal file
@@ -0,0 +1,216 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_UNORDERED_SET_H
|
||||
#define TINYSTL_UNORDERED_SET_H
|
||||
|
||||
#include "allocator.h"
|
||||
#include "buffer.h"
|
||||
#include "hash.h"
|
||||
#include "hash_base.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
template<typename Key, typename Alloc = TINYSTL_ALLOCATOR>
|
||||
class unordered_set {
|
||||
public:
|
||||
unordered_set();
|
||||
unordered_set(const unordered_set& other);
|
||||
~unordered_set();
|
||||
|
||||
unordered_set& operator=(const unordered_set& other);
|
||||
|
||||
typedef unordered_hash_iterator<const unordered_hash_node<Key, void> > const_iterator;
|
||||
typedef const_iterator iterator;
|
||||
|
||||
iterator begin() const;
|
||||
iterator end() const;
|
||||
|
||||
void clear();
|
||||
bool empty() const;
|
||||
size_t size() const;
|
||||
|
||||
iterator find(const Key& key) const;
|
||||
pair<iterator, bool> insert(const Key& key);
|
||||
void erase(iterator where);
|
||||
size_t erase(const Key& key);
|
||||
|
||||
void swap(unordered_set& other);
|
||||
|
||||
private:
|
||||
|
||||
typedef unordered_hash_node<Key, void>* pointer;
|
||||
|
||||
size_t m_size;
|
||||
tinystl::buffer<pointer, Alloc> m_buckets;
|
||||
};
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
unordered_set<Key, Alloc>::unordered_set()
|
||||
: m_size(0)
|
||||
{
|
||||
buffer_init<pointer, Alloc>(&m_buckets);
|
||||
buffer_resize<pointer, Alloc>(&m_buckets, 9, 0);
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
unordered_set<Key, Alloc>::unordered_set(const unordered_set& other)
|
||||
: m_size(other.m_size)
|
||||
{
|
||||
const size_t nbuckets = (size_t)(other.m_buckets.last - other.m_buckets.first);
|
||||
buffer_init<pointer, Alloc>(&m_buckets);
|
||||
buffer_resize<pointer, Alloc>(&m_buckets, 9, 0);
|
||||
|
||||
for (pointer* it = *other.m_buckets.first; it; it = it->next) {
|
||||
unordered_hash_node<Key, void>* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node<Key, void>))) unordered_hash_node<Key, void>(*it);
|
||||
newnode->next = newnode->prev = 0;
|
||||
unordered_hash_node_insert(newnode, hash(*it), m_buckets.first, nbuckets - 1);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
unordered_set<Key, Alloc>::~unordered_set() {
|
||||
clear();
|
||||
buffer_destroy<pointer, Alloc>(&m_buckets);
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
unordered_set<Key, Alloc>& unordered_set<Key, Alloc>::operator=(const unordered_set<Key, Alloc>& other) {
|
||||
unordered_set<Key, Alloc>(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline typename unordered_set<Key, Alloc>::iterator unordered_set<Key, Alloc>::begin() const {
|
||||
iterator cit;
|
||||
cit.node = *m_buckets.first;
|
||||
return cit;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline typename unordered_set<Key, Alloc>::iterator unordered_set<Key, Alloc>::end() const {
|
||||
iterator cit;
|
||||
cit.node = 0;
|
||||
return cit;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline bool unordered_set<Key, Alloc>::empty() const {
|
||||
return m_size == 0;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline size_t unordered_set<Key, Alloc>::size() const {
|
||||
return m_size;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline void unordered_set<Key, Alloc>::clear() {
|
||||
pointer it = *m_buckets.first;
|
||||
while (it) {
|
||||
const pointer next = it->next;
|
||||
it->~unordered_hash_node<Key, void>();
|
||||
Alloc::static_deallocate(it, sizeof(unordered_hash_node<Key, void>));
|
||||
|
||||
it = next;
|
||||
}
|
||||
|
||||
m_buckets.last = m_buckets.first;
|
||||
buffer_resize<pointer, Alloc>(&m_buckets, 9, 0);
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline typename unordered_set<Key, Alloc>::iterator unordered_set<Key, Alloc>::find(const Key& key) const {
|
||||
iterator result;
|
||||
result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first));
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline pair<typename unordered_set<Key, Alloc>::iterator, bool> unordered_set<Key, Alloc>::insert(const Key& key) {
|
||||
pair<iterator, bool> result;
|
||||
result.second = false;
|
||||
|
||||
result.first = find(key);
|
||||
if (result.first.node != 0)
|
||||
return result;
|
||||
|
||||
unordered_hash_node<Key, void>* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node<Key, void>))) unordered_hash_node<Key, void>(key);
|
||||
newnode->next = newnode->prev = 0;
|
||||
|
||||
const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first);
|
||||
unordered_hash_node_insert(newnode, hash(key), m_buckets.first, nbuckets - 1);
|
||||
|
||||
++m_size;
|
||||
if (m_size + 1 > 4 * nbuckets) {
|
||||
pointer root = *m_buckets.first;
|
||||
|
||||
const size_t newnbuckets = ((size_t)(m_buckets.last - m_buckets.first) - 1) * 8;
|
||||
m_buckets.last = m_buckets.first;
|
||||
buffer_resize<pointer, Alloc>(&m_buckets, newnbuckets + 1, 0);
|
||||
unordered_hash_node<Key, void>** buckets = m_buckets.first;
|
||||
|
||||
while (root) {
|
||||
const pointer next = root->next;
|
||||
root->next = root->prev = 0;
|
||||
unordered_hash_node_insert(root, hash(root->first), buckets, newnbuckets);
|
||||
root = next;
|
||||
}
|
||||
}
|
||||
|
||||
result.first.node = newnode;
|
||||
result.second = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline void unordered_set<Key, Alloc>::erase(iterator where) {
|
||||
unordered_hash_node_erase(where.node, hash(where.node->first), m_buckets.first, (size_t)(m_buckets.last - m_buckets.first) - 1);
|
||||
|
||||
where.node->~unordered_hash_node<Key, void>();
|
||||
Alloc::static_deallocate((void*)where.node, sizeof(unordered_hash_node<Key, void>));
|
||||
--m_size;
|
||||
}
|
||||
|
||||
template<typename Key, typename Alloc>
|
||||
inline size_t unordered_set<Key, Alloc>::erase(const Key& key) {
|
||||
const iterator it = find(key);
|
||||
if (it.node == 0)
|
||||
return 0;
|
||||
|
||||
erase(it);
|
||||
return 1;
|
||||
}
|
||||
|
||||
template <typename Key, typename Alloc>
|
||||
void unordered_set<Key, Alloc>::swap(unordered_set& other) {
|
||||
size_t tsize = other.m_size;
|
||||
other.m_size = m_size, m_size = tsize;
|
||||
buffer_swap(&m_buckets, &other.m_buckets);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
268
include/tinystl/vector.h
Normal file
268
include/tinystl/vector.h
Normal file
@@ -0,0 +1,268 @@
|
||||
/*-
|
||||
* Copyright 2012 Matthew Endsley
|
||||
* All rights reserved
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted providing that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef TINYSTL_VECTOR_H
|
||||
#define TINYSTL_VECTOR_H
|
||||
|
||||
#include "allocator.h"
|
||||
#include "buffer.h"
|
||||
#include "new.h"
|
||||
#include "stddef.h"
|
||||
|
||||
namespace tinystl {
|
||||
|
||||
template<typename T, typename Alloc = TINYSTL_ALLOCATOR>
|
||||
class vector {
|
||||
public:
|
||||
vector();
|
||||
vector(const vector& other);
|
||||
vector(size_t size);
|
||||
vector(size_t size, const T& value);
|
||||
vector(const T* first, const T* last);
|
||||
~vector();
|
||||
|
||||
vector& operator=(const vector& other);
|
||||
|
||||
void assign(const T* first, const T* last);
|
||||
|
||||
const T* data() const;
|
||||
T* data();
|
||||
size_t size() const;
|
||||
bool empty() const;
|
||||
|
||||
T& operator[](size_t idx);
|
||||
const T& operator[](size_t idx) const;
|
||||
|
||||
const T& back() const;
|
||||
T& back();
|
||||
|
||||
void resize(size_t size);
|
||||
void resize(size_t size, const T& value);
|
||||
void clear();
|
||||
void reserve(size_t capacity);
|
||||
|
||||
void push_back(const T& t);
|
||||
void pop_back();
|
||||
|
||||
void swap(vector& other);
|
||||
|
||||
typedef T value_type;
|
||||
|
||||
typedef T* iterator;
|
||||
iterator begin();
|
||||
iterator end();
|
||||
|
||||
typedef const T* const_iterator;
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
|
||||
void insert(iterator where, const T& value);
|
||||
void insert(iterator where, const T* first, const T* last);
|
||||
|
||||
iterator erase(iterator where);
|
||||
iterator erase(iterator first, iterator last);
|
||||
|
||||
iterator erase_unordered(iterator where);
|
||||
iterator erase_unordered(iterator first, iterator last);
|
||||
|
||||
private:
|
||||
buffer<T, Alloc> m_buffer;
|
||||
};
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline vector<T, Alloc>::vector() {
|
||||
buffer_init(&m_buffer);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline vector<T, Alloc>::vector(const vector& other) {
|
||||
buffer_init(&m_buffer);
|
||||
buffer_reserve(&m_buffer, other.size());
|
||||
buffer_insert(&m_buffer, m_buffer.last, other.m_buffer.first, other.m_buffer.last);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline vector<T, Alloc>::vector(size_t size) {
|
||||
buffer_init(&m_buffer);
|
||||
buffer_resize(&m_buffer, size, T());
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline vector<T, Alloc>::vector(size_t size, const T& value) {
|
||||
buffer_init(&m_buffer);
|
||||
buffer_resize(&m_buffer, size, value);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline vector<T, Alloc>::vector(const T* first, const T* last) {
|
||||
buffer_init(&m_buffer);
|
||||
buffer_insert(&m_buffer, m_buffer.last, first, last);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline vector<T, Alloc>::~vector() {
|
||||
buffer_destroy(&m_buffer);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline vector<T, Alloc>& vector<T, Alloc>::operator=(const vector& other) {
|
||||
vector(other).swap(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::assign(const T* first, const T* last) {
|
||||
buffer_clear(&m_buffer);
|
||||
buffer_insert(&m_buffer, m_buffer.last, first, last);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline const T* vector<T, Alloc>::data() const {
|
||||
return m_buffer.first;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline T* vector<T, Alloc>::data() {
|
||||
return m_buffer.first;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline size_t vector<T, Alloc>::size() const {
|
||||
return (size_t)(m_buffer.last - m_buffer.first);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline bool vector<T, Alloc>::empty() const {
|
||||
return m_buffer.last == m_buffer.first;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline T& vector<T, Alloc>::operator[](size_t idx) {
|
||||
return m_buffer.first[idx];
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline const T& vector<T, Alloc>::operator[](size_t idx) const {
|
||||
return m_buffer.first[idx];
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline const T& vector<T, Alloc>::back() const {
|
||||
return m_buffer.last[-1];
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline T& vector<T, Alloc>::back() {
|
||||
return m_buffer.last[-1];
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::resize(size_t size) {
|
||||
buffer_resize(&m_buffer, size, T());
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::resize(size_t size, const T& value) {
|
||||
buffer_resize(&m_buffer, size, value);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::clear() {
|
||||
buffer_clear(&m_buffer);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::reserve(size_t capacity) {
|
||||
buffer_reserve(&m_buffer, capacity);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::push_back(const T& t) {
|
||||
buffer_insert(&m_buffer, m_buffer.last, &t, &t + 1);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::pop_back() {
|
||||
buffer_erase(&m_buffer, m_buffer.last - 1, m_buffer.last);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::swap(vector& other) {
|
||||
buffer_swap(&m_buffer, &other.m_buffer);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline typename vector<T, Alloc>::iterator vector<T,Alloc>::begin() {
|
||||
return m_buffer.first;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline typename vector<T, Alloc>::iterator vector<T,Alloc>::end() {
|
||||
return m_buffer.last;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline typename vector<T, Alloc>::const_iterator vector<T,Alloc>::begin() const {
|
||||
return m_buffer.first;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline typename vector<T, Alloc>::const_iterator vector<T,Alloc>::end() const {
|
||||
return m_buffer.last;
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::insert(iterator where, const T& value) {
|
||||
buffer_insert(&m_buffer, where, &value, &value + 1);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline void vector<T, Alloc>::insert(iterator where, const T* first, const T* last) {
|
||||
buffer_insert(&m_buffer, where, first, last);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline typename vector<T, Alloc>::iterator vector<T, Alloc>::erase(iterator where) {
|
||||
return buffer_erase(&m_buffer, where, where + 1);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline typename vector<T, Alloc>::iterator vector<T, Alloc>::erase(iterator first, iterator last) {
|
||||
return buffer_erase(&m_buffer, first, last);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline typename vector<T, Alloc>::iterator vector<T, Alloc>::erase_unordered(iterator where) {
|
||||
return buffer_erase_unordered(&m_buffer, where, where + 1);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc>
|
||||
inline typename vector<T, Alloc>::iterator vector<T, Alloc>::erase_unordered(iterator first, iterator last) {
|
||||
return buffer_erase_unordered(&m_buffer, first, last);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user