summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bx/include/tinystl/buffer.h
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bx/include/tinystl/buffer.h')
-rw-r--r--3rdparty/bx/include/tinystl/buffer.h227
1 files changed, 227 insertions, 0 deletions
diff --git a/3rdparty/bx/include/tinystl/buffer.h b/3rdparty/bx/include/tinystl/buffer.h
new file mode 100644
index 00000000000..31654c64119
--- /dev/null
+++ b/3rdparty/bx/include/tinystl/buffer.h
@@ -0,0 +1,227 @@
+/*-
+ * 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 "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->capacity - (char*)b->first));
+ }
+
+ 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_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 size = (size_t)(b->last - b->first);
+ T* newfirst = (T*)Alloc::static_allocate(sizeof(T) * size);
+ buffer_move_urange(newfirst, b->first, b->last);
+ b->first = newfirst;
+ b->last = newfirst + size;
+ b->capacity = b->last;
+ }
+ }
+
+ 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