annotate foosdk/sdk/pfc/primitives.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 <functional>
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 #include "traits.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
6 #include "bit_array.h"
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
7
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
8 #define tabsize(x) ((size_t)(sizeof(x)/sizeof(*x)))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
9 #define PFC_TABSIZE(x) ((size_t)(sizeof(x)/sizeof(*x)))
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 // Retained for compatibility. Do not use. Use C++11 template<typename ... arg_t> instead.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
12 #define TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(THISCLASS,MEMBER,INITIALIZER) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
13 THISCLASS() : MEMBER() INITIALIZER \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
14 template<typename t_param1> THISCLASS(const t_param1 & p_param1) : MEMBER(p_param1) INITIALIZER \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
15 template<typename t_param1,typename t_param2> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2) : MEMBER(p_param1,p_param2) INITIALIZER \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
16 template<typename t_param1,typename t_param2,typename t_param3> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3) : MEMBER(p_param1,p_param2,p_param3) INITIALIZER \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
17 template<typename t_param1,typename t_param2,typename t_param3,typename t_param4> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4) : MEMBER(p_param1,p_param2,p_param3,p_param4) INITIALIZER \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
18 template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5) INITIALIZER \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
19 template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5,const t_param6 & p_param6) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6) INITIALIZER \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
20 template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6, typename t_param7> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5,const t_param6 & p_param6,const t_param7 & p_param7) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6,p_param7) INITIALIZER \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
21 template<typename t_param1,typename t_param2,typename t_param3,typename t_param4,typename t_param5,typename t_param6, typename t_param7, typename t_param8> THISCLASS(const t_param1 & p_param1,const t_param2 & p_param2,const t_param3 & p_param3,const t_param4 & p_param4,const t_param5 & p_param5,const t_param6 & p_param6,const t_param7 & p_param7, const t_param8 & p_param8) : MEMBER(p_param1,p_param2,p_param3,p_param4,p_param5,p_param6,p_param7, p_param8) INITIALIZER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
22
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
23 #define TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD(THISCLASS,MEMBER) TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(THISCLASS,MEMBER,{})
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
24
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
25
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
26 #ifdef _WIN32
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 #ifndef _MSC_VER
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
29 #error MSVC expected
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
30 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
31
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
32 // MSVC specific - part of fb2k ABI - cannot ever change on MSVC/Windows
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 #define PFC_DECLARE_EXCEPTION(NAME,BASECLASS,DEFAULTMSG) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
35 class NAME : public BASECLASS { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
36 public: \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
37 static const char * g_what() {return DEFAULTMSG;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
38 NAME() : BASECLASS(DEFAULTMSG,0) {} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
39 NAME(const char * p_msg) : BASECLASS(p_msg) {} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
40 NAME(const char * p_msg,int) : BASECLASS(p_msg,0) {} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
41 NAME(const NAME & p_source) : BASECLASS(p_source) {} \
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 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
45 template<typename t_exception> PFC_NORETURN inline void throw_exception_with_message(const char * p_message) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
46 throw t_exception(p_message);
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
50 #else
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
51
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
52 #define PFC_DECLARE_EXCEPTION(NAME,BASECLASS,DEFAULTMSG) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
53 class NAME : public BASECLASS { \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
54 public: \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
55 static const char * g_what() {return DEFAULTMSG;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
56 const char* what() const throw() {return DEFAULTMSG;} \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
57 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
58
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
59 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
60 template<typename t_base> class __exception_with_message_t : public t_base {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
61 private: typedef __exception_with_message_t<t_base> t_self;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
62 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
63 __exception_with_message_t(const char * p_message) : m_message(NULL) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
64 set_message(p_message);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
65 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
66 __exception_with_message_t() : m_message(NULL) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
67 __exception_with_message_t(const t_self & p_source) : m_message(NULL) {set_message(p_source.m_message);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
68
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
69 const char* what() const throw() {return m_message != NULL ? m_message : "unnamed exception";}
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 const t_self & operator=(const t_self & p_source) {set_message(p_source.m_message);}
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 ~__exception_with_message_t() throw() {cleanup();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
74
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
75 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
76 void set_message(const char * p_message) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
77 cleanup();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
78 if (p_message != NULL) m_message = strdup(p_message);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
79 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
80 void cleanup() throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
81 if (m_message != NULL) {free(m_message); m_message = NULL;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
82 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
83 char * m_message;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
84 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
85 template<typename t_exception> PFC_NORETURN void throw_exception_with_message(const char * p_message) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
86 throw __exception_with_message_t<t_exception>(p_message);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
87 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
88 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
89 #endif
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 namespace pfc {
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 template<typename p_type1,typename p_type2> class assert_same_type;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
94 template<typename p_type> class assert_same_type<p_type,p_type> {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
95
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
96 template<typename p_type1,typename p_type2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
97 class is_same_type { public: enum {value = false}; };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
98 template<typename p_type>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
99 class is_same_type<p_type,p_type> { public: enum {value = true}; };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
100
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
101 template<bool val> class static_assert_t;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
102 template<> class static_assert_t<true> {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
103
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
104 #define PFC_STATIC_ASSERT(X) { ::pfc::static_assert_t<(X)>(); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
105
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
106 template<typename t_type>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
107 void assert_raw_type() {static_assert_t< !traits_t<t_type>::needs_constructor && !traits_t<t_type>::needs_destructor >();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
108
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
109 template<typename t_type> class assert_byte_type;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
110 template<> class assert_byte_type<char> {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
111 template<> class assert_byte_type<unsigned char> {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
112 template<> class assert_byte_type<signed char> {};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
113
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
114
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
115 template<typename t_type> void __unsafe__memcpy_t(t_type * p_dst,const t_type * p_src,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
116 ::memcpy(reinterpret_cast<void*>(p_dst), reinterpret_cast<const void*>(p_src), p_count * sizeof(t_type));
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
119 template<typename t_type> void __unsafe__in_place_destructor_t(t_type & p_item) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
120 if constexpr (traits_t<t_type>::needs_destructor) try{ p_item.~t_type(); } catch(...) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
121 }
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 template<typename t_type> void __unsafe__in_place_constructor_t(t_type & p_item) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
124 if constexpr (traits_t<t_type>::needs_constructor) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
125 t_type * ret = new(&p_item) t_type;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
126 PFC_ASSERT(ret == &p_item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
127 (void) ret; // suppress warning
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
128 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
129 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
130
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
131 template<typename t_type> void __unsafe__in_place_destructor_array_t(t_type * p_items, t_size p_count) throw() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
132 if constexpr (traits_t<t_type>::needs_destructor) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
133 t_type * walk = p_items;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
134 for(t_size n=p_count;n;--n) __unsafe__in_place_destructor_t(*(walk++));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
135 }
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
138 template<typename t_type> t_type * __unsafe__in_place_constructor_array_t(t_type * p_items,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
139 if constexpr (traits_t<t_type>::needs_constructor) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
140 t_size walkptr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
141 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
142 for(walkptr=0;walkptr<p_count;++walkptr) __unsafe__in_place_constructor_t(p_items[walkptr]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
143 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
144 __unsafe__in_place_destructor_array_t(p_items,walkptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
145 throw;
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 return p_items;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
149 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
150
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
151 template<typename t_type> t_type * __unsafe__in_place_resize_array_t(t_type * p_items,t_size p_from,t_size p_to) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
152 if (p_from < p_to) __unsafe__in_place_constructor_array_t(p_items + p_from, p_to - p_from);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
153 else if (p_from > p_to) __unsafe__in_place_destructor_array_t(p_items + p_to, p_from - p_to);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
154 return p_items;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
155 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
156
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
157 template<typename t_type,typename t_copy> void __unsafe__in_place_constructor_copy_t(t_type & p_item,const t_copy & p_copyfrom) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
158 if constexpr (traits_t<t_type>::needs_constructor) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
159 t_type * ret = new(&p_item) t_type(p_copyfrom);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
160 PFC_ASSERT(ret == &p_item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
161 (void) ret; // suppress warning
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
162 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
163 p_item = p_copyfrom;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
164 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
165 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
166
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
167 template<typename t_type,typename t_copy> t_type * __unsafe__in_place_constructor_array_copy_t(t_type * p_items,t_size p_count, const t_copy * p_copyfrom) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
168 t_size walkptr = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
169 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
170 for(walkptr=0;walkptr<p_count;++walkptr) __unsafe__in_place_constructor_copy_t(p_items[walkptr],p_copyfrom[walkptr]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
171 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
172 __unsafe__in_place_destructor_array_t(p_items,walkptr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
173 throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
174 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
175 return p_items;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
176 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
177
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
178 template<typename t_type,typename t_copy> t_type * __unsafe__in_place_constructor_array_copy_partial_t(t_type * p_items,t_size p_count, const t_copy * p_copyfrom,t_size p_copyfrom_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
179 if (p_copyfrom_count > p_count) p_copyfrom_count = p_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
180 __unsafe__in_place_constructor_array_copy_t(p_items,p_copyfrom_count,p_copyfrom);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
181 try {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
182 __unsafe__in_place_constructor_array_t(p_items + p_copyfrom_count,p_count - p_copyfrom_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
183 } catch(...) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
184 __unsafe__in_place_destructor_array_t(p_items,p_copyfrom_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
185 throw;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
186 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
187 return p_items;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
188 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
189
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
190 template<typename t_ret> t_ret implicit_cast(t_ret val) {return val;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
191
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
192 template<typename t_ret,typename t_param>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
193 t_ret * safe_ptr_cast(t_param * p_param) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
194 if constexpr (pfc::is_same_type<t_ret,t_param>::value) return p_param;
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 if (p_param == NULL) return NULL;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
197 else return p_param;
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
201 typedef std::exception exception;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
202
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
203 PFC_DECLARE_EXCEPTION(exception_overflow,exception,"Overflow");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
204 PFC_DECLARE_EXCEPTION(exception_bug_check,exception,"Bug check");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
205 PFC_DECLARE_EXCEPTION(exception_invalid_params,exception_bug_check,"Invalid parameters");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
206 PFC_DECLARE_EXCEPTION(exception_unexpected_recursion,exception_bug_check,"Unexpected recursion");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
207 PFC_DECLARE_EXCEPTION(exception_not_implemented,exception_bug_check,"Feature not implemented");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
208 PFC_DECLARE_EXCEPTION(exception_dynamic_assert,exception_bug_check,"dynamic_assert failure");
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
209
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
210 template<typename t_ret,typename t_param>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
211 t_ret downcast_guarded(const t_param & p_param) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
212 t_ret temp = (t_ret) p_param;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
213 if ((t_param) temp != p_param) throw exception_overflow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
214 return temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
215 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
216
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
217 template<typename t_exception,typename t_ret,typename t_param>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
218 t_ret downcast_guarded_ex(const t_param & p_param) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
219 t_ret temp = (t_ret) p_param;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
220 if ((t_param) temp != p_param) throw t_exception();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
221 return temp;
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 template<typename t_acc,typename t_add>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
225 void accumulate_guarded(t_acc & p_acc, const t_add & p_add) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
226 t_acc delta = downcast_guarded<t_acc>(p_add);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
227 delta += p_acc;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
228 if (delta < p_acc) throw exception_overflow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
229 p_acc = delta;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
230 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
231
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
232 //deprecated
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
233 inline void bug_check_assert(bool p_condition, const char * p_msg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
234 if (!p_condition) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
235 PFC_ASSERT(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
236 throw_exception_with_message<exception_bug_check>(p_msg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
237 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
238 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
239 //deprecated
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
240 inline void bug_check_assert(bool p_condition) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
241 if (!p_condition) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
242 PFC_ASSERT(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
243 throw exception_bug_check();
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 inline void dynamic_assert(bool p_condition, const char * p_msg) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
248 if (!p_condition) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
249 PFC_ASSERT(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
250 throw_exception_with_message<exception_dynamic_assert>(p_msg);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
251 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
252 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
253 inline void dynamic_assert(bool p_condition) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
254 if (!p_condition) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
255 PFC_ASSERT(0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
256 throw exception_dynamic_assert();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
257 }
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
260 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
261 inline void swap_multi_t(T * p_buffer1,T * p_buffer2,t_size p_size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
262 T * walk1 = p_buffer1, * walk2 = p_buffer2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
263 for(t_size n=p_size;n;--n) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
264 T temp (* walk1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
265 *walk1 = *walk2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
266 *walk2 = temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
267 walk1++; walk2++;
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 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
270
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
271 template<typename T,t_size p_size>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
272 inline void swap_multi_t(T * p_buffer1,T * p_buffer2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
273 T * walk1 = p_buffer1, * walk2 = p_buffer2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
274 for(t_size n=p_size;n;--n) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
275 T temp (* walk1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
276 *walk1 = *walk2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
277 *walk2 = temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
278 walk1++; walk2++;
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 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
281
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 template<t_size p_size>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
284 inline void __unsafe__swap_raw_t(void * p_object1, void * p_object2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
285 if constexpr (p_size % sizeof(t_size) == 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
286 swap_multi_t<t_size,p_size/sizeof(t_size)>(reinterpret_cast<t_size*>(p_object1),reinterpret_cast<t_size*>(p_object2));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
287 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
288 swap_multi_t<t_uint8,p_size>(reinterpret_cast<t_uint8*>(p_object1),reinterpret_cast<t_uint8*>(p_object2));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
289 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
290 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
291
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
292 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
293 inline void swap_t(T & p_item1, T & p_item2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
294 if constexpr (traits_t<T>::realloc_safe) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
295 __unsafe__swap_raw_t<sizeof(T)>( reinterpret_cast<void*>( &p_item1 ), reinterpret_cast<void*>( &p_item2 ) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
296 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
297 T temp( std::move(p_item2) );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
298 p_item2 = std::move(p_item1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
299 p_item1 = std::move(temp);
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 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
302
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
303 //! This is similar to plain p_item1 = p_item2; assignment, but optimized for the case where p_item2 content is no longer needed later on. This can be overridden for specific classes for optimal performance. \n
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
304 //! p_item2 value is undefined after performing a move_t. For an example, in certain cases move_t will fall back to swap_t.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
305 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
306 inline void move_t(T & p_item1, T & p_item2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
307 p_item1 = std::move(p_item2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
308 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
309
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
310 template<typename t_array>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
311 t_size array_size_t(const t_array & p_array) {return p_array.get_size();}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
312
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
313 template<typename t_item, t_size p_width>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
314 t_size array_size_t(const t_item (&p_array)[p_width]) {return p_width;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
315
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
316 template<typename t_array, typename t_item> static bool array_isLast(const t_array & arr, const t_item & item) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
317 const t_size size = pfc::array_size_t(arr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
318 return size > 0 && arr[size-1] == item;
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 template<typename t_array, typename t_item> static bool array_isFirst(const t_array & arr, const t_item & item) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
321 const t_size size = pfc::array_size_t(arr);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
322 return size > 0 && arr[0] == item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
323 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
324
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
325 template<typename t_array,typename t_filler>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
326 inline void fill_t(t_array & p_buffer,const t_size p_count, const t_filler & p_filler) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
327 for(t_size n=0;n<p_count;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
328 p_buffer[n] = p_filler;
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
331 template<typename t_array,typename t_filler>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
332 inline void fill_ptr_t(t_array * p_buffer,const t_size p_count, const t_filler & p_filler) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
333 for(t_size n=0;n<p_count;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
334 p_buffer[n] = p_filler;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
335 }
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 template<typename t_item1, typename t_item2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
338 inline int compare_t(const t_item1 & p_item1, const t_item2 & p_item2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
339 if (p_item1 < p_item2) return -1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
340 else if (p_item1 > p_item2) return 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
341 else return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
342 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
343
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
344 //! For use with avltree/map etc.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
345 class comparator_default {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
346 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
347 template<typename t_item1,typename t_item2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
348 inline static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {return pfc::compare_t(p_item1,p_item2);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
349 };
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 template<typename t_comparator = pfc::comparator_default> class comparator_pointer { public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
352 template<typename t_item1,typename t_item2> static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {return t_comparator::compare(*p_item1,*p_item2);}
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
355 template<typename t_primary,typename t_secondary> class comparator_dual { public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
356 template<typename t_item1,typename t_item2> static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
357 int state = t_primary::compare(p_item1,p_item2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
358 if (state != 0) return state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
359 return t_secondary::compare(p_item1,p_item2);
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 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
362
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
363 class comparator_memcmp {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
364 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
365 template<typename t_item1,typename t_item2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
366 inline static int compare(const t_item1 & p_item1,const t_item2 & p_item2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
367 static_assert_t<sizeof(t_item1) == sizeof(t_item2)>();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
368 return memcmp(&p_item1,&p_item2,sizeof(t_item1));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
369 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
370 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
371
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
372 template<typename t_source1, typename t_source2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
373 t_size subtract_sorted_lists_calculate_count(const t_source1 & p_source1, const t_source2 & p_source2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
374 t_size walk1 = 0, walk2 = 0, walk_out = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
375 const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
376 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
377 int state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
378 if (walk1 < max1 && walk2 < max2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
379 state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
380 } else if (walk1 < max1) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
381 state = -1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
382 } else if (walk2 < max2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
383 state = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
384 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
385 break;
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 if (state < 0) walk_out++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
388 if (state <= 0) walk1++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
389 if (state >= 0) walk2++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
390 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
391 return walk_out;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
392 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
393
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
394 //! Subtracts p_source2 contents from p_source1 and stores result in p_destination. Both source lists must be sorted.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
395 //! Note: duplicates will be carried over (and ignored for p_source2).
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
396 template<typename t_destination, typename t_source1, typename t_source2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
397 void subtract_sorted_lists(t_destination & p_destination,const t_source1 & p_source1, const t_source2 & p_source2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
398 p_destination.set_size(subtract_sorted_lists_calculate_count(p_source1,p_source2));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
399 t_size walk1 = 0, walk2 = 0, walk_out = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
400 const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
401 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
402 int state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
403 if (walk1 < max1 && walk2 < max2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
404 state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
405 } else if (walk1 < max1) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
406 state = -1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
407 } else if (walk2 < max2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
408 state = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
409 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
410 break;
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
413
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
414 if (state < 0) p_destination[walk_out++] = p_source1[walk1];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
415 if (state <= 0) walk1++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
416 if (state >= 0) walk2++;
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
420 template<typename t_source1, typename t_source2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
421 t_size merge_sorted_lists_calculate_count(const t_source1 & p_source1, const t_source2 & p_source2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
422 t_size walk1 = 0, walk2 = 0, walk_out = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
423 const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
424 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
425 int state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
426 if (walk1 < max1 && walk2 < max2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
427 state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
428 } else if (walk1 < max1) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
429 state = -1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
430 } else if (walk2 < max2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
431 state = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
432 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
433 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
434 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
435 if (state <= 0) walk1++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
436 if (state >= 0) walk2++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
437 walk_out++;
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 return walk_out;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
440 }
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 //! Merges p_source1 and p_source2, storing content in p_destination. Both source lists must be sorted.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
443 //! Note: duplicates will be carried over.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
444 template<typename t_destination, typename t_source1, typename t_source2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
445 void merge_sorted_lists(t_destination & p_destination,const t_source1 & p_source1, const t_source2 & p_source2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
446 p_destination.set_size(merge_sorted_lists_calculate_count(p_source1,p_source2));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
447 t_size walk1 = 0, walk2 = 0, walk_out = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
448 const t_size max1 = p_source1.get_size(), max2 = p_source2.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
449 for(;;) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
450 int state;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
451 if (walk1 < max1 && walk2 < max2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
452 state = pfc::compare_t(p_source1[walk1],p_source2[walk2]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
453 } else if (walk1 < max1) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
454 state = -1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
455 } else if (walk2 < max2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
456 state = 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
457 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
458 break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
459 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
460 if (state < 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
461 p_destination[walk_out] = p_source1[walk1++];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
462 } else if (state > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
463 p_destination[walk_out] = p_source2[walk2++];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
464 } else {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
465 p_destination[walk_out] = p_source1[walk1];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
466 walk1++; walk2++;
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 walk_out++;
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 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
471
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
472 template<typename t_array, typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
473 inline t_size append_t(t_array & p_array, T && p_item)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
474 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
475 t_size old_count = p_array.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
476 p_array.set_size(old_count + 1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
477 p_array[old_count] = std::forward<T>(p_item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
478 return old_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
479 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
480
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
481 template<typename t_array,typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
482 inline t_size append_swap_t(t_array & p_array,T & p_item)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
483 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
484 t_size old_count = p_array.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
485 p_array.set_size(old_count + 1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
486 swap_t(p_array[old_count],p_item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
487 return old_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
488 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
489
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
490 template<typename t_array>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
491 inline t_size insert_uninitialized_t(t_array & p_array,t_size p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
492 t_size old_count = p_array.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
493 if (p_index > old_count) p_index = old_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
494 p_array.set_size(old_count + 1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
495 for(t_size n=old_count;n>p_index;n--) move_t(p_array[n], p_array[n-1]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
496 return p_index;
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 template<typename t_array,typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
500 inline t_size insert_t(t_array & p_array,const T & p_item,t_size p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
501 t_size old_count = p_array.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
502 if (p_index > old_count) p_index = old_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
503 p_array.set_size(old_count + 1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
504 for(t_size n=old_count;n>p_index;n--)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
505 move_t(p_array[n], p_array[n-1]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
506 p_array[p_index] = p_item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
507 return p_index;
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 template<typename array1_t, typename array2_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
510 void insert_array_t( array1_t & outArray, size_t insertAt, array2_t const & inArray, size_t inArraySize) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
511 const size_t oldSize = outArray.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
512 if (insertAt > oldSize) insertAt = oldSize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
513 const size_t newSize = oldSize + inArraySize;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
514 outArray.set_size( newSize );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
515 for(size_t m = oldSize; m != insertAt; --m) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
516 move_t( outArray[ m - 1 + inArraySize], outArray[m - 1] );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
517 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
518 for(size_t w = 0; w < inArraySize; ++w) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
519 outArray[ insertAt + w ] = inArray[ w ];
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
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
523 template<typename t_array,typename in_array_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
524 inline t_size insert_multi_t(t_array & p_array,const in_array_t & p_items, size_t p_itemCount, t_size p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
525 const t_size old_count = p_array.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
526 const size_t new_count = old_count + p_itemCount;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
527 if (p_index > old_count) p_index = old_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
528 p_array.set_size(new_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
529 size_t toMove = old_count - p_index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
530 for(size_t w = 0; w < toMove; ++w) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
531 move_t( p_array[new_count - 1 - w], p_array[old_count - 1 - w] );
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
532 }
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 for(size_t w = 0; w < p_itemCount; ++w) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
535 p_array[p_index+w] = p_items[w];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
536 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
537
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
538 return p_index;
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 template<typename t_array,typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
541 inline t_size insert_swap_t(t_array & p_array,T & p_item,t_size p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
542 t_size old_count = p_array.get_size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
543 if (p_index > old_count) p_index = old_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
544 p_array.set_size(old_count + 1);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
545 for(t_size n=old_count;n>p_index;n--)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
546 swap_t(p_array[n],p_array[n-1]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
547 swap_t(p_array[p_index],p_item);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
548 return p_index;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
549 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
550
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
551
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
552 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
553 inline T max_t(const T & item1, const T & item2) {return item1 > item2 ? item1 : item2;};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
554
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
555 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
556 inline T min_t(const T & item1, const T & item2) {return item1 < item2 ? item1 : item2;};
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
557
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
558 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
559 inline T abs_t(T item) {return item<0 ? -item : item;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
560
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
561 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
562 inline T sqr_t(T item) {return item * item;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
563
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
564 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
565 inline T clip_t(const T & p_item, const T & p_min, const T & p_max) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
566 if (p_item < p_min) return p_min;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
567 else if (p_item <= p_max) return p_item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
568 else return p_max;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
569 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
570
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
571
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
572
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
573
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
574
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
575 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
576 inline void delete_t(T* ptr) {delete ptr;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
577
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
578 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
579 inline void delete_array_t(T* ptr) {delete[] ptr;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
580
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
581 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
582 inline T* clone_t(T* ptr) {return new T(*ptr);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
583
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
584
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
585 template<typename t_exception,typename t_int>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
586 inline t_int mul_safe_t(t_int p_val1,t_int p_val2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
587 if (p_val1 == 0 || p_val2 == 0) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
588 t_int temp = (t_int) (p_val1 * p_val2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
589 if (temp / p_val1 != p_val2) throw t_exception();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
590 return temp;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
591 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
592 template<typename t_int>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
593 t_int multiply_guarded(t_int v1, t_int v2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
594 return mul_safe_t<exception_overflow>(v1, v2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
595 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
596 template<typename t_int> t_int add_unsigned_clipped(t_int v1, t_int v2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
597 t_int v = v1 + v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
598 if (v < v1) return ~0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
599 return v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
600 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
601 template<typename t_int> t_int sub_unsigned_clipped(t_int v1, t_int v2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
602 t_int v = v1 - v2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
603 if (v > v1) return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
604 return v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
605 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
606 template<typename t_int> void acc_unsigned_clipped(t_int & v1, t_int v2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
607 v1 = add_unsigned_clipped(v1, v2);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
608 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
609
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
610 template<typename t_src,typename t_dst>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
611 void memcpy_t(t_dst* p_dst,const t_src* p_src,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
612 for(t_size n=0;n<p_count;n++) p_dst[n] = p_src[n];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
613 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
614
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
615 template<typename t_dst,typename t_src>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
616 void copy_array_loop_t(t_dst & p_dst,const t_src & p_src,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
617 for(t_size n=0;n<p_count;n++) p_dst[n] = p_src[n];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
618 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
619
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
620 template<typename t_src,typename t_dst>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
621 void memcpy_backwards_t(t_dst * p_dst,const t_src * p_src,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
622 p_dst += p_count; p_src += p_count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
623 for(t_size n=0;n<p_count;n++) *(--p_dst) = *(--p_src);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
624 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
625
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
626 template<typename T,typename t_val>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
627 void memset_t(T * p_buffer,const t_val & p_val,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
628 for(t_size n=0;n<p_count;n++) p_buffer[n] = p_val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
629 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
630
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
631 template<typename T,typename t_val>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
632 void memset_t(T &p_buffer,const t_val & p_val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
633 const t_size width = pfc::array_size_t(p_buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
634 for(t_size n=0;n<width;n++) p_buffer[n] = p_val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
635 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
636
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
637 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
638 void memset_null_t(T * p_buffer,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
639 for(t_size n=0;n<p_count;n++) p_buffer[n] = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
640 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
641
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
642 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
643 void memset_null_t(T &p_buffer) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
644 const t_size width = pfc::array_size_t(p_buffer);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
645 for(t_size n=0;n<width;n++) p_buffer[n] = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
646 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
647
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
648 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
649 void memmove_t(T* p_dst,const T* p_src,t_size p_count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
650 if (p_dst == p_src) {/*do nothing*/}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
651 else if (p_dst > p_src && p_dst < p_src + p_count) memcpy_backwards_t<T>(p_dst,p_src,p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
652 else memcpy_t<T>(p_dst,p_src,p_count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
653 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
654
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
655 template<typename TVal> void memxor_t(TVal * out, const TVal * s1, const TVal * s2, t_size count) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
656 for(t_size walk = 0; walk < count; ++walk) out[walk] = s1[walk] ^ s2[walk];
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
657 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
658 inline static void memxor(void * target, const void * source1, const void * source2, t_size size) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
659 memxor_t( reinterpret_cast<t_uint8*>(target), reinterpret_cast<const t_uint8*>(source1), reinterpret_cast<const t_uint8*>(source2), size);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
660 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
661
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
662 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
663 T* new_ptr_check_t(T* p_ptr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
664 if (p_ptr == NULL) throw std::bad_alloc();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
665 return p_ptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
666 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
667
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
668 template<typename T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
669 int sgn_t(const T & p_val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
670 if (p_val < 0) return -1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
671 else if (p_val > 0) return 1;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
672 else return 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
673 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
674
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
675 template<typename T> const T* empty_string_t();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
676
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
677 template<> inline const char * empty_string_t<char>() {return "";}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
678 template<> inline const wchar_t * empty_string_t<wchar_t>() {return L"";}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
679
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
680
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
681 template<typename type_t, typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
682 type_t replace_t(type_t & p_var,arg_t && p_newval) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
683 auto oldval = std::move(p_var);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
684 p_var = std::forward<arg_t>(p_newval);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
685 return oldval;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
686 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
687
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
688 template<typename t_type>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
689 t_type replace_null_t(t_type & p_var) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
690 t_type ret = std::move(p_var);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
691 p_var = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
692 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
693 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
694
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
695 template<t_size p_size_pow2>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
696 inline bool is_ptr_aligned_t(const void * p_ptr) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
697 static_assert_t< (p_size_pow2 & (p_size_pow2 - 1)) == 0 >();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
698 return ( ((t_size)p_ptr) & (p_size_pow2-1) ) == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
699 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
700
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
701
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
702 template<typename t_array>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
703 void array_rangecheck_t(const t_array & p_array,t_size p_index) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
704 if (p_index >= pfc::array_size_t(p_array)) throw pfc::exception_overflow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
705 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
706
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
707 template<typename t_array>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
708 void array_rangecheck_t(const t_array & p_array,t_size p_from,t_size p_to) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
709 if (p_from > p_to) throw pfc::exception_overflow();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
710 array_rangecheck_t(p_array,p_from); array_rangecheck_t(p_array,p_to);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
711 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
712
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
713 t_int32 rint32(double p_val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
714 t_int64 rint64(double p_val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
715
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
716 //! Returns amount of items left.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
717 template<typename array_t, typename pred_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
718 inline size_t remove_if_t( array_t & arr, pred_t pred ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
719 const size_t inCount = arr.size();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
720 size_t walk = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
721
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
722 for (;; ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
723 if ( walk == inCount ) return inCount;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
724 if ( pred(arr[walk]) ) break;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
725 ++ walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
726 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
727
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
728 size_t total = walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
729
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
730 ++ walk; // already know that at walk is pred() positive
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
731
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
732 for( ; walk < inCount; ++ walk ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
733 if ( !pred(arr[walk] ) ) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
734 move_t(arr[total++], arr[walk]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
735 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
736 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
737 arr.resize(total);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
738
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
739 return total;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
740 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
741
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
742 //! Returns amount of items left.
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
743 template<typename t_array>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
744 inline t_size remove_mask_t(t_array & p_array,const bit_array & p_mask)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
745 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
746 t_size n,count = p_array.size(), total = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
747
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
748 n = total = p_mask.find(true,0,count);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
749
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
750 if (n<count)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
751 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
752 for(n=p_mask.find(false,n+1,count-n-1);n<count;n=p_mask.find(false,n+1,count-n-1))
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
753 move_t(p_array[total++],p_array[n]);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
754
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
755 p_array.resize(total);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
756
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
757 return total;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
758 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
759 else return count;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
760 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
761
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
762 template<typename t_array,typename t_compare>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
763 t_size find_duplicates_sorted_t(t_array p_array,t_size p_count,t_compare p_compare,bit_array_var & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
764 t_size ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
765 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
766 if (p_count > 0)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
767 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
768 p_out.set(0,false);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
769 for(n=1;n<p_count;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
770 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
771 bool found = p_compare(p_array[n-1],p_array[n]) == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
772 if (found) ret++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
773 p_out.set(n,found);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
774 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
775 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
776 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
777 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
778
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
779 template<typename t_array,typename t_compare,typename t_permutation>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
780 t_size find_duplicates_sorted_permutation_t(t_array p_array,t_size p_count,t_compare p_compare,t_permutation const & p_permutation,bit_array_var & p_out) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
781 t_size ret = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
782 t_size n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
783 if (p_count > 0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
784 p_out.set(p_permutation[0],false);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
785 for(n=1;n<p_count;n++)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
786 {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
787 bool found = p_compare(p_array[p_permutation[n-1]],p_array[p_permutation[n]]) == 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
788 if (found) ret++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
789 p_out.set(p_permutation[n],found);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
790 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
791 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
792 return ret;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
793 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
794
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
795 template<typename t_char>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
796 t_size strlen_t(const t_char * p_string,t_size p_length = ~0) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
797 for(t_size walk = 0;;walk++) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
798 if (walk >= p_length || p_string[walk] == 0) return walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
799 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
800 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
801
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
802
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
803 template<typename t_array>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
804 class __list_to_array_enumerator {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
805 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
806 __list_to_array_enumerator(t_array & p_array) : m_walk(), m_array(p_array) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
807 template<typename t_item>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
808 void operator() (const t_item & p_item) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
809 PFC_ASSERT(m_walk < m_array.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
810 m_array[m_walk++] = p_item;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
811 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
812 void finalize() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
813 PFC_ASSERT(m_walk == m_array.get_size());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
814 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
815 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
816 t_size m_walk;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
817 t_array & m_array;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
818 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
819
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
820 template<typename t_list,typename t_array>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
821 void list_to_array(t_array & p_array,const t_list & p_list) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
822 p_array.set_size(p_list.get_count());
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
823 __list_to_array_enumerator<t_array> enumerator(p_array);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
824 p_list.enumerate(enumerator);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
825 enumerator.finalize();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
826 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
827
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
828 template<typename t_receiver>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
829 class enumerator_add_item {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
830 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
831 enumerator_add_item(t_receiver & p_receiver) : m_receiver(p_receiver) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
832 template<typename t_item> void operator() (const t_item & p_item) {m_receiver.add_item(p_item);}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
833 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
834 t_receiver & m_receiver;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
835 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
836
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
837 template<typename t_receiver,typename t_giver>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
838 void overwrite_list_enumerated(t_receiver & p_receiver,const t_giver & p_giver) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
839 enumerator_add_item<t_receiver> wrapper(p_receiver);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
840 p_giver.enumerate(wrapper);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
841 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
842
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
843 template<typename t_receiver,typename t_giver>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
844 void copy_list_enumerated(t_receiver & p_receiver,const t_giver & p_giver) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
845 p_receiver.remove_all();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
846 overwrite_list_enumerated(p_receiver,p_giver);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
847 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
848
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
849 inline bool lxor(bool p_val1,bool p_val2) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
850 return p_val1 == !p_val2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
851 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
852
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
853 template<typename t_val>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
854 inline void min_acc(t_val & p_acc,const t_val & p_val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
855 if (p_val < p_acc) p_acc = p_val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
856 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
857
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
858 template<typename t_val>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
859 inline void max_acc(t_val & p_acc,const t_val & p_val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
860 if (p_val > p_acc) p_acc = p_val;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
861 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
862
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
863 t_uint64 pow_int(t_uint64 base, t_uint64 exp) noexcept;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
864 double exp_int(double base, int exp) noexcept;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
865
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
866
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
867 template<typename t_val>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
868 class incrementScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
869 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
870 incrementScope(t_val & i) : v(i) {++v;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
871 ~incrementScope() {--v;}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
872 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
873 t_val & v;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
874 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
875 template<typename obj_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
876 incrementScope<obj_t> autoIncrement(obj_t& v) { return incrementScope<obj_t>(v); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
877
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
878 constexpr inline unsigned countBits32(uint32_t i) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
879 const uint32_t mask = 0x11111111;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
880 uint32_t acc = i & mask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
881 acc += (i >> 1) & mask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
882 acc += (i >> 2) & mask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
883 acc += (i >> 3) & mask;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
884
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
885 const uint32_t mask2 = 0x0F0F0F0F;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
886 uint32_t acc2 = acc & mask2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
887 acc2 += (acc >> 4) & mask2;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
888
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
889 const uint32_t mask3 = 0x00FF00FF;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
890 uint32_t acc3 = acc2 & mask3;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
891 acc3 += (acc2 >> 8) & mask3;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
892
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
893 return (acc3 & 0xFFFF) + ((acc3 >> 16) & 0xFFFF);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
894 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
895
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
896 // Forward declarations
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
897 template<typename t_to,typename t_from>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
898 void copy_array_t(t_to & p_to,const t_from & p_from);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
899
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
900 template<typename t_array,typename t_value>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
901 void fill_array_t(t_array & p_array,const t_value & p_value);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
902
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
903 // Generic no-op for breakpointing stuff
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
904 inline void nop() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
905
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
906 template<class T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
907 class vartoggle_t {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
908 T oldval; T& var;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
909 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
910 vartoggle_t(const vartoggle_t&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
911 void operator=(const vartoggle_t&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
912 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
913 vartoggle_t(T& p_var, arg_t&& val) : var(p_var) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
914 oldval = std::move(var);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
915 var = std::forward<arg_t>(val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
916 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
917 ~vartoggle_t() { var = std::move(oldval); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
918 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
919
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
920 template<typename T, typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
921 vartoggle_t<T> autoToggle(T& p_var, arg_t&& val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
922 return vartoggle_t<T>(p_var, std::forward<arg_t>(val));
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
923 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
924
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
925 template<class T>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
926 class vartoggle_volatile_t {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
927 T oldval; volatile T& var;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
928 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
929 template<typename arg_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
930 vartoggle_volatile_t(volatile T& p_var, arg_t && val) : var(p_var) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
931 oldval = std::move(var);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
932 var = std::forward<arg_t>(val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
933 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
934 ~vartoggle_volatile_t() { var = std::move(oldval); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
935 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
936
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
937 typedef vartoggle_t<bool> booltoggle;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
938
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
939 template<typename obj_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
940 class singleton {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
941 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
942 static obj_t instance;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
943 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
944 template<typename obj_t>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
945 obj_t singleton<obj_t>::instance;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
946
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
947 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
948 #define PFC_SINGLETON(X) ::pfc::singleton<X>::instance
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
949
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
950
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
951 #define PFC_CLASS_NOT_COPYABLE(THISCLASSNAME,THISTYPE) \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
952 THISCLASSNAME(const THISTYPE&) = delete; \
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
953 const THISTYPE & operator=(const THISTYPE &) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
954
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
955 #define PFC_CLASS_NOT_COPYABLE_EX(THISTYPE) PFC_CLASS_NOT_COPYABLE(THISTYPE,THISTYPE)
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
956
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
957
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
958 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
959 template<typename t_char>
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
960 t_size strlen_max_t(const t_char* ptr, t_size max) noexcept {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
961 PFC_ASSERT(ptr != NULL || max == 0);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
962 t_size n = 0;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
963 while (n < max && ptr[n] != 0) n++;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
964 return n;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
965 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
966
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
967 inline t_size strlen_max(const char* ptr, t_size max) noexcept { return strlen_max_t(ptr, max); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
968 inline t_size wcslen_max(const wchar_t* ptr, t_size max) noexcept { return strlen_max_t(ptr, max); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
969
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
970 #ifdef _WINDOWS
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
971 inline t_size tcslen_max(const TCHAR* ptr, t_size max) noexcept { return strlen_max_t(ptr, max); }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
972 #endif
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
973 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
974
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
975 namespace pfc {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
976 class autoScope {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
977 public:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
978 autoScope() {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
979 autoScope(std::function<void()>&& f) : m_cleanup(std::move(f)) {}
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
980
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
981 template<typename what_t> void increment(what_t& obj) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
982 reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
983 ++obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
984 m_cleanup = [&obj] { --obj; };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
985 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
986 template<typename what_t, typename arg_t> void toggle(what_t& obj, arg_t && val) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
987 reset();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
988 what_t old = obj;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
989 obj = std::forward<arg_t>(val);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
990 m_cleanup = [v = std::move(old), &obj]{
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
991 obj = std::move(v);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
992 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
993 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
994 void operator() (std::function<void()>&& f) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
995 reset(); m_cleanup = std::move(f);
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
996 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
997
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
998 ~autoScope() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
999 if (m_cleanup) m_cleanup();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1000 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1001
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1002 void cancel() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1003 m_cleanup = nullptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1004 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1005
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1006 void reset() {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1007 if (m_cleanup) {
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1008 m_cleanup();
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1009 m_cleanup = nullptr;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1010 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1011 }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1012
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1013 autoScope(const autoScope&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1014 void operator=(const autoScope&) = delete;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1015
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1016 operator bool() const { return !!m_cleanup; }
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1017 private:
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1018 std::function<void()> m_cleanup;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1019 };
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1020 typedef autoScope onLeaving;
20d02a178406 *: check in everything else
Paper <paper@tflc.us>
parents:
diff changeset
1021 }