annotate foosdk/sdk/pfc/alloc.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1 #pragma once
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
2
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
3 #include "primitives.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
4
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
5 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7 static void * raw_malloc(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 return p_size > 0 ? new_ptr_check_t(malloc(p_size)) : NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
10
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
11 static void raw_free(void * p_block) throw() {free(p_block);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 inline void* raw_realloc(void * p_ptr,t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 if (p_size == 0) {raw_free(p_ptr); return NULL;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 else if (p_ptr == NULL) return raw_malloc(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 else return pfc::new_ptr_check_t(::realloc(p_ptr,p_size));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 inline bool raw_realloc_inplace(void * p_block,t_size p_size) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 if (p_block == NULL) return p_size == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 #ifdef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22 if (p_size == 0) return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 return _expand(p_block,p_size) != NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25 return false;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
27 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
28
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 t_size calc_array_width(t_size p_width) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31 return pfc::mul_safe_t<std::bad_alloc,t_size>(p_width,sizeof(T));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
33
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
34 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 T * __raw_malloc_t(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 return reinterpret_cast<T*>(raw_malloc(calc_array_width<T>(p_size)));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 void __raw_free_t(T * p_block) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 raw_free(reinterpret_cast<void*>(p_block));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
42 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
43
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
44 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 T * __raw_realloc_t(T * p_block,t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 return reinterpret_cast<T*>(raw_realloc(p_block,calc_array_width<T>(p_size)));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
47 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
48
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
49 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 bool __raw_realloc_inplace_t(T * p_block,t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51 return raw_realloc_inplace(p_block,calc_array_width<T>(p_size));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 template<typename t_exception,typename t_int>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 inline t_int safe_shift_left_t(t_int p_val,t_size p_shift = 1) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 t_int newval = p_val << p_shift;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58 if (newval >> p_shift != p_val) throw t_exception();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 return newval;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 template<typename t_item> class alloc_dummy {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 private: typedef alloc_dummy<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 alloc_dummy() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 void set_size(t_size p_size) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 t_size get_size() const {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68 const t_item & operator[](t_size p_index) const {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 t_item & operator[](t_size p_index) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
70
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
71 bool is_ptr_owned(const void * p_item) const {return false;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
72
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
73 //set to true when we prioritize speed over memory usage
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74 enum { alloc_prioritizes_speed = false };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 //not mandatory
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 const t_item * get_ptr() const {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 t_item * get_ptr() {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 void prealloc(t_size) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 void force_reset() {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 void move_from(t_self &) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 const t_self & operator=(const t_self &) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 alloc_dummy(const t_self&) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 template<typename t_item>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 bool is_pointer_in_range(const t_item * p_buffer,t_size p_buffer_size,const void * p_pointer) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 return p_pointer >= reinterpret_cast<const void*>(p_buffer) && p_pointer < reinterpret_cast<const void*>(p_buffer + p_buffer_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
90 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
91
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
92
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
93 //! Simple inefficient fully portable allocator.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 template<typename t_item> class alloc_simple {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95 private: typedef alloc_simple<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 alloc_simple() : m_data(NULL), m_size(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 void set_size(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 if (p_size != m_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100 t_item * l_data = NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 if (p_size > 0) l_data = new t_item[p_size];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103 pfc::memcpy_t(l_data,m_data,pfc::min_t(m_size,p_size));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105 delete[] l_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108 delete[] m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 m_data = l_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113 t_size get_size() const {return m_size;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114 const t_item & operator[](t_size p_index) const {PFC_ASSERT(p_index < m_size); return m_data[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 t_item & operator[](t_size p_index) {PFC_ASSERT(p_index < m_size); return m_data[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 bool is_ptr_owned(const void * p_item) const {return is_pointer_in_range(get_ptr(),get_size(),p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
117
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
118 enum { alloc_prioritizes_speed = false };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 t_item * get_ptr() {return m_data;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 const t_item * get_ptr() const {return m_data;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
122
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
123 void prealloc(t_size) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 void force_reset() {set_size(0);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 ~alloc_simple() {delete[] m_data;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 void move_from(t_self & other) noexcept {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 delete[] m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130 m_data = replace_null_t(other.m_data);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 m_size = replace_null_t(other.m_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 const t_self & operator=(const t_self &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 alloc_simple(const t_self&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
136
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
137 t_item * m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 t_size m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 template<typename t_item> class __array_fast_helper_t {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 typedef __array_fast_helper_t<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 __array_fast_helper_t() : m_buffer(NULL), m_size(0), m_size_total(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
146
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
147
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
148 void set_size(t_size p_size,t_size p_size_total) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 PFC_ASSERT(p_size <= p_size_total);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150 PFC_ASSERT(m_size <= m_size_total);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 if (p_size_total > m_size_total) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 resize_storage(p_size_total);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 resize_content(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 resize_content(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156 resize_storage(p_size_total);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 t_size get_size() const {return m_size;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 t_size get_size_total() const {return m_size_total;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 const t_item & operator[](t_size p_index) const {PFC_ASSERT(p_index < m_size); return m_buffer[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 t_item & operator[](t_size p_index) {PFC_ASSERT(p_index < m_size); return m_buffer[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166 ~__array_fast_helper_t() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 set_size(0,0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 t_item * get_ptr() {return m_buffer;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 const t_item * get_ptr() const {return m_buffer;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 bool is_ptr_owned(const void * p_item) const {return is_pointer_in_range(m_buffer,m_size_total,p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 void move_from(t_self & other) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 set_size(0,0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 m_buffer = replace_null_t(other.m_buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 m_size = replace_null_t(other.m_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177 m_size_total = replace_null_t(other.m_size_total);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 const t_self & operator=(const t_self &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 __array_fast_helper_t(const t_self &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 void resize_content(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 if constexpr (traits_t<t_item>::needs_constructor || traits_t<t_item>::needs_destructor) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 if (p_size > m_size) {//expand
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 do {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 __unsafe__in_place_constructor_t(m_buffer[m_size]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189 m_size++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 } while(m_size < p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191 } else if (p_size < m_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 __unsafe__in_place_destructor_array_t(m_buffer + p_size, m_size - p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
195 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
196 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
198 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
199
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
200 void resize_storage(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 PFC_ASSERT( m_size <= m_size_total );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202 PFC_ASSERT( m_size <= p_size );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 if (m_size_total != p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 if constexpr (pfc::traits_t<t_item>::realloc_safe) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 m_buffer = pfc::__raw_realloc_t(m_buffer,p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 m_size_total = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 } else if (__raw_realloc_inplace_t(m_buffer,p_size)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 //success
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209 m_size_total = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 t_item * newbuffer = pfc::__raw_malloc_t<t_item>(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 pfc::__unsafe__in_place_constructor_array_copy_t(newbuffer,m_size,m_buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 pfc::__raw_free_t(newbuffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216 throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 pfc::__unsafe__in_place_destructor_array_t(m_buffer,m_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 pfc::__raw_free_t(m_buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 m_buffer = newbuffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 m_size_total = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
222 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
223 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
224 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 t_item * m_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 t_size m_size,m_size_total;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 template<typename t_item> class __array_lite_helper_t {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 typedef __array_lite_helper_t<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 __array_lite_helper_t() : m_buffer(NULL), m_size(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 void set_size(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 if (p_size > m_size) { // expand
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 resize_storage(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 resize_content(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 } else if (p_size < m_size) { // shrink
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 resize_content(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 resize_storage(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
244 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
245 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
246
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
247
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 t_size get_size() const {return m_size;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 const t_item & operator[](t_size p_index) const {PFC_ASSERT(p_index < m_size); return m_buffer[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 t_item & operator[](t_size p_index) {PFC_ASSERT(p_index < m_size); return m_buffer[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 ~__array_lite_helper_t() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 set_size(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 t_item * get_ptr() {return m_buffer;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 const t_item * get_ptr() const {return m_buffer;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 bool is_ptr_owned(const void * p_item) const {return is_pointer_in_range(m_buffer,m_size,p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
258
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
259 void move_from(t_self & other) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 set_size(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 m_buffer = replace_null_t(other.m_buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 m_size = replace_null_t(other.m_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 const t_self & operator=(const t_self &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 __array_lite_helper_t(const t_self &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
268
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
269 void resize_content(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270 if constexpr (traits_t<t_item>::needs_constructor || traits_t<t_item>::needs_destructor) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 if (p_size > m_size) {//expand
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 do {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 __unsafe__in_place_constructor_t(m_buffer[m_size]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 m_size++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 } while(m_size < p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 } else if (p_size < m_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 __unsafe__in_place_destructor_array_t(m_buffer + p_size, m_size - p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
279 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
280 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
282 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
283 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 void resize_storage(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 PFC_ASSERT( m_size <= p_size );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 if constexpr (pfc::traits_t<t_item>::realloc_safe) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 m_buffer = pfc::__raw_realloc_t(m_buffer,p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 //m_size_total = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 } else if (__raw_realloc_inplace_t(m_buffer,p_size)) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291 //success
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 //m_size_total = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 t_item * newbuffer = pfc::__raw_malloc_t<t_item>(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 pfc::__unsafe__in_place_constructor_array_copy_t(newbuffer,m_size,m_buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 pfc::__raw_free_t(newbuffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
300 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
301 pfc::__unsafe__in_place_destructor_array_t(m_buffer,m_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302 pfc::__raw_free_t(m_buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 m_buffer = newbuffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 //m_size_total = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 t_item * m_buffer;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309 t_size m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312 template<typename t_item> class alloc_standard {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 private: typedef alloc_standard<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315 alloc_standard() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 void set_size(t_size p_size) {m_content.set_size(p_size);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 t_size get_size() const {return m_content.get_size();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
319
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
320 const t_item & operator[](t_size p_index) const {return m_content[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 t_item & operator[](t_size p_index) {return m_content[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 const t_item * get_ptr() const {return m_content.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324 t_item * get_ptr() {return m_content.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 bool is_ptr_owned(const void * p_item) const {return m_content.is_ptr_owned(p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 void prealloc(t_size p_size) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 void force_reset() {set_size(0);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
329
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
330 enum { alloc_prioritizes_speed = false };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 void move_from(t_self & other) { m_content.move_from(other.m_content); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 alloc_standard(const t_self &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 const t_self & operator=(const t_self&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
336
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
337 __array_lite_helper_t<t_item> m_content;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 template<typename t_item> class alloc_fast {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 private: typedef alloc_fast<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343 alloc_fast() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 void set_size(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 t_size size_base = m_data.get_size_total();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 if (size_base == 0) size_base = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 while(size_base < p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 size_base = safe_shift_left_t<std::bad_alloc,t_size>(size_base,1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
350 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
351 while(size_base >> 2 > p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 size_base >>= 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
353 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
354 m_data.set_size(p_size,size_base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 t_size get_size() const {return m_data.get_size();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 const t_item & operator[](t_size p_index) const {return m_data[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 t_item & operator[](t_size p_index) {return m_data[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
360
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
361 const t_item * get_ptr() const {return m_data.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362 t_item * get_ptr() {return m_data.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 bool is_ptr_owned(const void * p_item) const {return m_data.is_ptr_owned(p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 void prealloc(t_size) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 void force_reset() {m_data.set_size(0,0);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 enum { alloc_prioritizes_speed = true };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 void move_from(t_self & other) { m_data.move_from(other.m_data); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371 alloc_fast(const t_self &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 const t_self & operator=(const t_self&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 __array_fast_helper_t<t_item> m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 template<typename t_item> class alloc_fast_aggressive {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 private: typedef alloc_fast_aggressive<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 alloc_fast_aggressive() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 void set_size(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 t_size size_base = m_data.get_size_total();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 if (size_base == 0) size_base = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 while(size_base < p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 size_base = safe_shift_left_t<std::bad_alloc,t_size>(size_base,1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
386 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
387 m_data.set_size(p_size,size_base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 void prealloc(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 if (p_size > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 t_size size_base = m_data.get_size_total();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393 if (size_base == 0) size_base = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 while(size_base < p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 size_base = safe_shift_left_t<std::bad_alloc,t_size>(size_base,1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 m_data.set_size(m_data.get_size(),size_base);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 t_size get_size() const {return m_data.get_size();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 const t_item & operator[](t_size p_index) const {;return m_data[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 t_item & operator[](t_size p_index) {return m_data[p_index];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 const t_item * get_ptr() const {return m_data.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 t_item * get_ptr() {return m_data.get_ptr();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 bool is_ptr_owned(const void * p_item) const {return m_data.is_ptr_owned(p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 void force_reset() {m_data.set_size(0,0);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 enum { alloc_prioritizes_speed = true };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
411
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
412 void move_from(t_self & other) { m_data.move_from(other.m_data); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414 alloc_fast_aggressive(const t_self &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 const t_self & operator=(const t_self&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 __array_fast_helper_t<t_item> m_data;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
417 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
418
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
419 template<t_size p_width> class alloc_fixed {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 template<typename t_item> class alloc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422 private: typedef alloc<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 alloc() : m_size(0) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426 void set_size(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 static_assert_t<sizeof(m_array) == sizeof(t_item[p_width])>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 if (p_size > p_width) throw pfc::exception_overflow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 else if (p_size > m_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 __unsafe__in_place_constructor_array_t(get_ptr()+m_size,p_size-m_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 } else if (p_size < m_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 __unsafe__in_place_destructor_array_t(get_ptr()+p_size,m_size-p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 m_size = p_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
438
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
439 ~alloc() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 if constexpr (pfc::traits_t<t_item>::needs_destructor) set_size(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
441 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
442
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443 t_size get_size() const {return m_size;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 t_item * get_ptr() {return reinterpret_cast<t_item*>(&m_array);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446 const t_item * get_ptr() const {return reinterpret_cast<const t_item*>(&m_array);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 const t_item & operator[](t_size n) const {return get_ptr()[n];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 t_item & operator[](t_size n) {return get_ptr()[n];}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450 bool is_ptr_owned(const void * p_item) const {return is_pointer_in_range(get_ptr(),p_width,p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 void prealloc(t_size) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 void force_reset() {set_size(0);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454 enum { alloc_prioritizes_speed = false };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 void move_from(t_self & other) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 const size_t count = other.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 set_size( count );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 for(size_t w = 0; w < count; ++w) this->get_ptr()[w] = other.get_ptr()[w];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462 alloc(const t_self&) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463 const t_self& operator=(const t_self&) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 t_uint8 m_array[sizeof(t_item[p_width])];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 t_size m_size;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
467 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
468 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
469
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
470 template<t_size p_width, template<typename> class t_alloc = alloc_standard > class alloc_hybrid {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 template<typename t_item> class alloc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 private: typedef alloc<t_item> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 alloc() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 void set_size(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 if (p_size > p_width) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 m_fixed.set_size(p_width);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480 m_variable.set_size(p_size - p_width);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 m_fixed.set_size(p_size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 m_variable.set_size(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 t_item & operator[](t_size p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 PFC_ASSERT(p_index < get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489 if (p_index < p_width) return m_fixed[p_index];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 else return m_variable[p_index - p_width];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493 const t_item & operator[](t_size p_index) const {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 PFC_ASSERT(p_index < get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495 if (p_index < p_width) return m_fixed[p_index];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 else return m_variable[p_index - p_width];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
497 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
498
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
499 t_size get_size() const {return m_fixed.get_size() + m_variable.get_size();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500 bool is_ptr_owned(const void * p_item) const {return m_fixed.is_ptr_owned(p_item) || m_variable.is_ptr_owned(p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501 void prealloc(t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502 if (p_size > p_width) m_variable.prealloc(p_size - p_width);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504 void force_reset() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505 m_fixed.force_reset(); m_variable.force_reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507 enum { alloc_prioritizes_speed = t_alloc<t_item>::alloc_prioritizes_speed };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
508
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
509 void move_from(t_self & other) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 m_fixed.move_from(other.m_fixed);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511 m_variable.move_from(other.m_variable);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514 alloc(const t_self&) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
515 const t_self& operator=(const t_self&) {throw pfc::exception_not_implemented();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
516
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
517 typename alloc_fixed<p_width>::template alloc<t_item> m_fixed;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
518 t_alloc<t_item> m_variable;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
519 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
520 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
521
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
522 template<typename t_item> class traits_t<alloc_simple<t_item> > : public traits_default_movable {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
523 template<typename t_item> class traits_t<__array_fast_helper_t<t_item> > : public traits_default_movable {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
524 template<typename t_item> class traits_t<alloc_standard<t_item> > : public pfc::traits_t<__array_fast_helper_t<t_item> > {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
525 template<typename t_item> class traits_t<alloc_fast<t_item> > : public pfc::traits_t<__array_fast_helper_t<t_item> > {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
526 template<typename t_item> class traits_t<alloc_fast_aggressive<t_item> > : public pfc::traits_t<__array_fast_helper_t<t_item> > {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
527
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
528 #if 0//not working (compiler bug?)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
529 template<t_size p_width,typename t_item> class traits_t<typename alloc_fixed<p_width>::template alloc<t_item> > : public pfc::traits_t<t_item> {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
530 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
531 enum {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
532 needs_constructor = true,
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
533 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
534 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
535
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
536 template<t_size p_width,template<typename> class t_alloc,typename t_item>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
537 class traits_t<typename alloc_hybrid<p_width,t_alloc>::template alloc<t_item> > : public traits_combined<t_alloc,typename alloc_fixed<p_width>::template alloc<t_item> > {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
538 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
539
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
540
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
541 };