foobar2000 SDK  2015-08-03
other.cpp
Go to the documentation of this file.
1 #include "pfc.h"
2 #ifdef _MSC_VER
3 #include <intrin.h>
4 #include <assert.h>
5 #endif
6 #ifndef _MSC_VER
7 #include <signal.h>
8 #endif
9 
10 #if defined(__ANDROID__)
11 #include <android/log.h>
12 #endif
13 
14 #include <math.h>
15 
16 namespace pfc {
17  bool permutation_is_valid(t_size const * order, t_size count) {
18  bit_array_bittable found(count);
19  for(t_size walk = 0; walk < count; ++walk) {
20  if (order[walk] >= count) return false;
21  if (found[walk]) return false;
22  found.set(walk,true);
23  }
24  return true;
25  }
26  void permutation_validate(t_size const * order, t_size count) {
27  if (!permutation_is_valid(order,count)) throw exception_invalid_permutation();
28  }
29 
30  t_size permutation_find_reverse(t_size const * order, t_size count, t_size value) {
31  if (value >= count) return ~0;
32  for(t_size walk = 0; walk < count; ++walk) {
33  if (order[walk] == value) return walk;
34  }
35  return ~0;
36  }
37 
38  void create_move_items_permutation(t_size * p_output,t_size p_count,const bit_array & p_selection,int p_delta) {
39  t_size * const order = p_output;
40  const t_size count = p_count;
41 
42  pfc::array_t<bool> selection; selection.set_size(p_count);
43 
44  for(t_size walk = 0; walk < count; ++walk) {
45  order[walk] = walk;
46  selection[walk] = p_selection[walk];
47  }
48 
49  if (p_delta<0)
50  {
51  for(;p_delta<0;p_delta++)
52  {
53  t_size idx;
54  for(idx=1;idx<count;idx++)
55  {
56  if (selection[idx] && !selection[idx-1])
57  {
58  pfc::swap_t(order[idx],order[idx-1]);
59  pfc::swap_t(selection[idx],selection[idx-1]);
60  }
61  }
62  }
63  }
64  else
65  {
66  for(;p_delta>0;p_delta--)
67  {
68  t_size idx;
69  for(idx=count-2;(int)idx>=0;idx--)
70  {
71  if (selection[idx] && !selection[idx+1])
72  {
73  pfc::swap_t(order[idx],order[idx+1]);
74  pfc::swap_t(selection[idx],selection[idx+1]);
75  }
76  }
77  }
78  }
79  }
80 }
81 
82 void order_helper::g_swap(t_size * data,t_size ptr1,t_size ptr2)
83 {
84  t_size temp = data[ptr1];
85  data[ptr1] = data[ptr2];
86  data[ptr2] = temp;
87 }
88 
89 
91 {
92  t_size prev = val, next = order[val];
93  while(next != val)
94  {
95  prev = next;
96  next = order[next];
97  }
98  return prev;
99 }
100 
101 
102 void order_helper::g_reverse(t_size * order,t_size base,t_size count)
103 {
104  t_size max = count>>1;
105  t_size n;
106  t_size base2 = base+count-1;
107  for(n=0;n<max;n++)
108  g_swap(order,base+n,base2-n);
109 }
110 
111 
112 void pfc::crash() {
113 #ifdef _MSC_VER
114  __debugbreak();
115 #else
116 
117 #if defined(__ANDROID__) && PFC_DEBUG
118  nixSleep(1);
119 #endif
120 
121  raise(SIGINT);
122 #endif
123 }
124 
125 
126 void pfc::byteswap_raw(void * p_buffer,const t_size p_bytes) {
127  t_uint8 * ptr = (t_uint8*)p_buffer;
128  t_size n;
129  for(n=0;n<p_bytes>>1;n++) swap_t(ptr[n],ptr[p_bytes-n-1]);
130 }
131 
132 void pfc::outputDebugLine(const char * msg) {
133 #ifdef _WIN32
134  OutputDebugString(pfc::stringcvt::string_os_from_utf8(PFC_string_formatter() << msg << "\n") );
135 #elif defined(__ANDROID__)
136  __android_log_write(ANDROID_LOG_INFO, "Debug", msg);
137 #else
138  printf("%s\n", msg);
139 #endif
140 }
141 
142 #if PFC_DEBUG
143 
144 #ifdef _WIN32
145 void pfc::myassert_win32(const wchar_t * _Message, const wchar_t *_File, unsigned _Line) {
146  if (IsDebuggerPresent()) pfc::crash();
147  _wassert(_Message,_File,_Line);
148 }
149 #else
150 
151 void pfc::myassert(const char * _Message, const char *_File, unsigned _Line)
152 {
153  PFC_DEBUGLOG << "Assert failure: \"" << _Message << "\" in: " << _File << " line " << _Line;
154  crash();
155 }
156 #endif
157 
158 #endif
159 
160 
162  t_uint64 mul = base;
163  t_uint64 val = 1;
164  t_uint64 mask = 1;
165  while(exp != 0) {
166  if (exp & mask) {
167  val *= mul;
168  exp ^= mask;
169  }
170  mul = mul * mul;
171  mask <<= 1;
172  }
173  return val;
174 }
175 
176 double pfc::exp_int( const double base, const int expS ) {
177  // return pow(base, (double)v);
178 
179  bool neg;
180  unsigned exp;
181  if (expS < 0) {
182  neg = true;
183  exp = (unsigned) -expS;
184  } else {
185  neg = false;
186  exp = (unsigned) expS;
187  }
188  double v = 1.0;
189  if (true) {
190  if (exp) {
191  double mul = base;
192  for(;;) {
193  if (exp & 1) v *= mul;
194  exp >>= 1;
195  if (exp == 0) break;
196  mul *= mul;
197  }
198  }
199  } else {
200  for(unsigned i = 0; i < exp; ++i) {
201  v *= base;
202  }
203  }
204  if (neg) v = 1.0 / v;
205  return v;
206 }
207 
208 
209 t_int32 pfc::rint32(double p_val) { return (t_int32)floor(p_val + 0.5); }
210 t_int64 pfc::rint64(double p_val) { return (t_int64)floor(p_val + 0.5); }
void outputDebugLine(const char *msg)
Definition: other.cpp:132
double exp_int(double base, int exp)
Definition: other.cpp:176
uint8_t t_uint8
Definition: int_types.h:9
t_uint64 pow_int(t_uint64 base, t_uint64 exp)
Definition: other.cpp:161
void byteswap_raw(void *p_buffer, t_size p_bytes)
Definition: other.cpp:126
uint64_t t_uint64
Definition: int_types.h:3
Generic variable bit_array implementation. Needs to be initialized with requested array size before ...
Bit array interface class, constant version (you can only retrieve values). Range of valid indexes d...
Definition: bit_array.h:6
void set(t_size n, bool val)
static void g_swap(t_size *p_data, t_size ptr1, t_size ptr2)
Definition: other.cpp:82
void printf(const char *,...)
Definition: console.cpp:37
void permutation_validate(t_size const *order, t_size count)
For critical sanity checks. Speed: O(n), allocates memory.
Definition: other.cpp:26
int32_t t_int32
Definition: int_types.h:4
t_size permutation_find_reverse(t_size const *order, t_size count, t_size value)
Definition: other.cpp:30
size_t t_size
Definition: int_types.h:48
void crash()
Definition: other.cpp:112
void set_size(t_size p_size)
Definition: array.h:104
static void g_reverse(t_size *order, t_size base, t_size count)
Definition: other.cpp:102
t_int64 rint64(double p_val)
Definition: other.cpp:210
t_int32 rint32(double p_val)
Definition: other.cpp:209
bool permutation_is_valid(t_size const *order, t_size count)
For critical sanity checks. Speed: O(n), allocates memory.
Definition: other.cpp:17
void create_move_items_permutation(t_size *p_output, t_size p_count, const class bit_array &p_selection, int p_delta)
Creates a permutation that moves selected items in a list box by the specified delta-offset.
static t_size g_find_reverse(const t_size *order, t_size val)
Insecure - may deadlock or crash on invalid permutation content. In theory faster than walking the pe...
Definition: other.cpp:90
void myassert(const char *_Message, const char *_File, unsigned _Line)
Definition: other.cpp:151
void swap_t(T &p_item1, T &p_item2)
Definition: primitives.h:285
void myassert_win32(const wchar_t *_Message, const wchar_t *_File, unsigned _Line)
Definition: other.cpp:145
void nixSleep(double seconds)
int64_t t_int64
Definition: int_types.h:2