foobar2000 SDK  2015-01-14
other.cpp
Go to the documentation of this file.
1 #include "pfc.h"
2 #ifdef _MSC_VER
3 #include <intrin.h>
4 #endif
5 #ifndef _MSC_VER
6 #include <signal.h>
7 #endif
8 
9 namespace pfc {
10  bool permutation_is_valid(t_size const * order, t_size count) {
11  bit_array_bittable found(count);
12  for(t_size walk = 0; walk < count; ++walk) {
13  if (order[walk] >= count) return false;
14  if (found[walk]) return false;
15  found.set(walk,true);
16  }
17  return true;
18  }
19  void permutation_validate(t_size const * order, t_size count) {
20  if (!permutation_is_valid(order,count)) throw exception_invalid_permutation();
21  }
22 
23  t_size permutation_find_reverse(t_size const * order, t_size count, t_size value) {
24  if (value >= count) return ~0;
25  for(t_size walk = 0; walk < count; ++walk) {
26  if (order[walk] == value) return walk;
27  }
28  return ~0;
29  }
30 
31  void create_move_items_permutation(t_size * p_output,t_size p_count,const bit_array & p_selection,int p_delta) {
32  t_size * const order = p_output;
33  const t_size count = p_count;
34 
35  pfc::array_t<bool> selection; selection.set_size(p_count);
36 
37  for(t_size walk = 0; walk < count; ++walk) {
38  order[walk] = walk;
39  selection[walk] = p_selection[walk];
40  }
41 
42  if (p_delta<0)
43  {
44  for(;p_delta<0;p_delta++)
45  {
46  t_size idx;
47  for(idx=1;idx<count;idx++)
48  {
49  if (selection[idx] && !selection[idx-1])
50  {
51  pfc::swap_t(order[idx],order[idx-1]);
52  pfc::swap_t(selection[idx],selection[idx-1]);
53  }
54  }
55  }
56  }
57  else
58  {
59  for(;p_delta>0;p_delta--)
60  {
61  t_size idx;
62  for(idx=count-2;(int)idx>=0;idx--)
63  {
64  if (selection[idx] && !selection[idx+1])
65  {
66  pfc::swap_t(order[idx],order[idx+1]);
67  pfc::swap_t(selection[idx],selection[idx+1]);
68  }
69  }
70  }
71  }
72  }
73 }
74 
75 void order_helper::g_swap(t_size * data,t_size ptr1,t_size ptr2)
76 {
77  t_size temp = data[ptr1];
78  data[ptr1] = data[ptr2];
79  data[ptr2] = temp;
80 }
81 
82 
84 {
85  t_size prev = val, next = order[val];
86  while(next != val)
87  {
88  prev = next;
89  next = order[next];
90  }
91  return prev;
92 }
93 
94 
95 void order_helper::g_reverse(t_size * order,t_size base,t_size count)
96 {
97  t_size max = count>>1;
98  t_size n;
99  t_size base2 = base+count-1;
100  for(n=0;n<max;n++)
101  g_swap(order,base+n,base2-n);
102 }
103 
104 
105 void pfc::crash() {
106 #ifdef _MSC_VER
107  __debugbreak();
108 #else
109  raise(SIGINT);
110 #endif
111 }
112 
113 
114 void pfc::byteswap_raw(void * p_buffer,const t_size p_bytes) {
115  t_uint8 * ptr = (t_uint8*)p_buffer;
116  t_size n;
117  for(n=0;n<p_bytes>>1;n++) swap_t(ptr[n],ptr[p_bytes-n-1]);
118 }
119 
120 #if defined(_DEBUG) && defined(_WIN32)
121 void pfc::myassert(const wchar_t * _Message, const wchar_t *_File, unsigned _Line) {
122  if (IsDebuggerPresent()) pfc::crash();
123  _wassert(_Message,_File,_Line);
124 }
125 #endif
126 
127 
129  t_uint64 mul = base;
130  t_uint64 val = 1;
131  t_uint64 mask = 1;
132  while(exp != 0) {
133  if (exp & mask) {
134  val *= mul;
135  exp ^= mask;
136  }
137  mul = mul * mul;
138  mask <<= 1;
139  }
140  return val;
141 }
142 
143 double pfc::exp_int( const double base, const int expS ) {
144  // return pow(base, (double)v);
145 
146  bool neg;
147  unsigned exp;
148  if (expS < 0) {
149  neg = true;
150  exp = (unsigned) -expS;
151  } else {
152  neg = false;
153  exp = (unsigned) expS;
154  }
155  double v = 1.0;
156  if (true) {
157  if (exp) {
158  double mul = base;
159  for(;;) {
160  if (exp & 1) v *= mul;
161  exp >>= 1;
162  if (exp == 0) break;
163  mul *= mul;
164  }
165  }
166  } else {
167  for(unsigned i = 0; i < exp; ++i) {
168  v *= base;
169  }
170  }
171  if (neg) v = 1.0 / v;
172  return v;
173 }
double exp_int(double base, int exp)
Definition: other.cpp:143
uint8_t t_uint8
Definition: int_types.h:9
t_uint64 pow_int(t_uint64 base, t_uint64 exp)
Definition: other.cpp:128
void byteswap_raw(void *p_buffer, t_size p_bytes)
Definition: other.cpp:114
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:75
void permutation_validate(t_size const *order, t_size count)
For critical sanity checks. Speed: O(n), allocates memory.
Definition: other.cpp:19
t_size permutation_find_reverse(t_size const *order, t_size count, t_size value)
Definition: other.cpp:23
size_t t_size
Definition: int_types.h:48
void crash()
Definition: other.cpp:105
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:95
void myassert(const wchar_t *_Message, const wchar_t *_File, unsigned _Line)
Definition: other.cpp:121
bool permutation_is_valid(t_size const *order, t_size count)
For critical sanity checks. Speed: O(n), allocates memory.
Definition: other.cpp:10
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:83
void swap_t(T &p_item1, T &p_item2)
Definition: primitives.h:285