foobar2000 SDK  2015-08-03
other.h
Go to the documentation of this file.
1 #ifndef _PFC_OTHER_H_
2 #define _PFC_OTHER_H_
3 
4 namespace pfc {
5  template<class T>
6  class vartoggle_t {
7  T oldval; T & var;
8  public:
9  vartoggle_t(T & p_var,const T & val) : var(p_var) {
10  oldval = var;
11  var = val;
12  }
13  ~vartoggle_t() {var = oldval;}
14  };
15 
17 };
18 
19 #ifdef _MSC_VER
20 
22 {
23  unsigned old_val;
24  unsigned mask;
25 public:
26  inline fpu_control(unsigned p_mask,unsigned p_val)
27  {
28  mask = p_mask;
29  _controlfp_s(&old_val,p_val,mask);
30  }
31  inline ~fpu_control()
32  {
33  unsigned dummy;
34  _controlfp_s(&dummy,old_val,mask);
35  }
36 };
37 
39 {
40 public:
41  fpu_control_roundnearest() : fpu_control(_MCW_RC,_RC_NEAR) {}
42 };
43 
45 {
46 public:
47  fpu_control_flushdenormal() : fpu_control(_MCW_DN,_DN_FLUSH) {}
48 };
49 
51 {
52 public:
53  fpu_control_default() : fpu_control(_MCW_DN|_MCW_RC,_DN_FLUSH|_RC_NEAR) {}
54 };
55 
56 #ifdef _M_IX86
57 class sse_control {
58 public:
59  sse_control(unsigned p_mask,unsigned p_val) : m_mask(p_mask) {
60  __control87_2(p_val,p_mask,NULL,&m_oldval);
61  }
63  __control87_2(m_oldval,m_mask,NULL,&m_oldval);
64  }
65 private:
66  unsigned m_mask,m_oldval;
67 };
69 public:
70  sse_control_flushdenormal() : sse_control(_MCW_DN,_DN_FLUSH) {}
71 };
72 #endif
73 
74 #endif
75 
76 namespace pfc {
77 
79  public:
80  template<typename T> static void release(T* p_ptr) {delete p_ptr;}
81  };
83  public:
84  template<typename T> static void release(T* p_ptr) {delete[] p_ptr;}
85  };
86  class releaser_free {
87  public:
88  static void release(void * p_ptr) {free(p_ptr);}
89  };
90 
92  template<typename T,typename t_releaser = releaser_delete >
93  class ptrholder_t {
94  private:
96  public:
97  inline ptrholder_t(T* p_ptr) : m_ptr(p_ptr) {}
98  inline ptrholder_t() : m_ptr(NULL) {}
99  inline ~ptrholder_t() {t_releaser::release(m_ptr);}
100  inline bool is_valid() const {return m_ptr != NULL;}
101  inline bool is_empty() const {return m_ptr == NULL;}
102  inline T* operator->() const {return m_ptr;}
103  inline T* get_ptr() const {return m_ptr;}
104  inline void release() {t_releaser::release(replace_null_t(m_ptr));;}
105  inline void attach(T * p_ptr) {release(); m_ptr = p_ptr;}
106  inline const t_self & operator=(T * p_ptr) {set(p_ptr);return *this;}
107  inline T* detach() {return pfc::replace_null_t(m_ptr);}
108  inline T& operator*() const {return *m_ptr;}
109 
110  inline t_self & operator<<(t_self & p_source) {attach(p_source.detach());return *this;}
111  inline t_self & operator>>(t_self & p_dest) {p_dest.attach(detach());return *this;}
112 
113  //deprecated
114  inline void set(T * p_ptr) {attach(p_ptr);}
115  private:
116  ptrholder_t(const t_self &) {throw pfc::exception_not_implemented();}
117  const t_self & operator=(const t_self & ) {throw pfc::exception_not_implemented();}
118 
120  };
121 
122  //avoid "void&" breakage
123  template<typename t_releaser>
124  class ptrholder_t<void,t_releaser> {
125  private:
126  typedef void T;
128  public:
129  inline ptrholder_t(T* p_ptr) : m_ptr(p_ptr) {}
130  inline ptrholder_t() : m_ptr(NULL) {}
131  inline ~ptrholder_t() {t_releaser::release(m_ptr);}
132  inline bool is_valid() const {return m_ptr != NULL;}
133  inline bool is_empty() const {return m_ptr == NULL;}
134  inline T* operator->() const {return m_ptr;}
135  inline T* get_ptr() const {return m_ptr;}
136  inline void release() {t_releaser::release(replace_null_t(m_ptr));;}
137  inline void attach(T * p_ptr) {release(); m_ptr = p_ptr;}
138  inline const t_self & operator=(T * p_ptr) {set(p_ptr);return *this;}
139  inline T* detach() {return pfc::replace_null_t(m_ptr);}
140 
141  inline t_self & operator<<(t_self & p_source) {attach(p_source.detach());return *this;}
142  inline t_self & operator>>(t_self & p_dest) {p_dest.attach(detach());return *this;}
143 
144  //deprecated
145  inline void set(T * p_ptr) {attach(p_ptr);}
146  private:
147  ptrholder_t(const t_self &) {throw pfc::exception_not_implemented();}
148  const t_self & operator=(const t_self & ) {throw pfc::exception_not_implemented();}
149 
150  T* m_ptr;
151  };
152 
153  void crash();
154  void outputDebugLine(const char * msg);
155 
156  class debugLog : public string_formatter {
157  public:
158  ~debugLog() { outputDebugLine(this->get_ptr()); }
159  };
160 #define PFC_DEBUGLOG ::pfc::debugLog()._formatter()
161 
162 
163  template<typename t_type,t_type p_initval>
165  public:
166  int_container_helper() : m_val(p_initval) {}
167  t_type m_val;
168  };
169 
170 
171 
172  //warning: not multi-thread-safe
173  template<typename t_base>
174  class instanceTracker : public t_base {
175  private:
177  public:
178  TEMPLATE_CONSTRUCTOR_FORWARD_FLOOD_WITH_INITIALIZER(instanceTracker,t_base,{g_list += this;});
179 
180  instanceTracker(const t_self & p_other) : t_base( (const t_base &)p_other) {g_list += this;}
181  ~instanceTracker() {g_list -= this;}
182 
184  static const t_list & instanceList() {return g_list;}
185  template<typename t_callback> static void forEach(t_callback & p_callback) {instanceList().enumerate(p_callback);}
186  private:
187  static t_list g_list;
188  };
189 
190  template<typename t_base>
192 
193 
194  //warning: not multi-thread-safe
195  template<typename TClass>
197  private:
199  public:
200  instanceTrackerV2(const t_self & p_other) {g_list += static_cast<TClass*>(this);}
201  instanceTrackerV2() {g_list += static_cast<TClass*>(this);}
202  ~instanceTrackerV2() {g_list -= static_cast<TClass*>(this);}
203 
205  static const t_instanceList & instanceList() {return g_list;}
206  template<typename t_callback> static void forEach(t_callback & p_callback) {instanceList().enumerate(p_callback);}
207  private:
208  static t_instanceList g_list;
209  };
210 
211  template<typename TClass>
213 
214 
216  bool m_flag;
218 
219  };
221  public:
222  objDestructNotify() : m_data() {}
224  set();
225  }
226 
227  void set() {
228  objDestructNotifyData * w = m_data;
229  while(w) {
230  w->m_flag = true; w = w->m_next;
231  }
232  }
234  };
235 
237  public:
239  m_next = m_obj->m_data;
240  m_obj->m_data = this;
241  }
243  if (!m_flag) m_obj->m_data = m_next;
244  }
245  bool get() const {return m_flag;}
246  PFC_CLASS_NOT_COPYABLE_EX(objDestructNotifyScope)
247  private:
248  objDestructNotify * m_obj;
249 
250  };
251 
252 
253  class bigmem {
254  public:
255  enum {slice = 1024*1024};
256  bigmem() : m_size() {}
257  ~bigmem() {clear();}
258 
259  void resize(size_t newSize) {
260  clear();
261  m_data.set_size( (newSize + slice - 1) / slice );
262  m_data.fill_null();
263  for(size_t walk = 0; walk < m_data.get_size(); ++walk) {
264  size_t thisSlice = slice;
265  if (walk + 1 == m_data.get_size()) {
266  size_t cut = newSize % slice;
267  if (cut) thisSlice = cut;
268  }
269  void* ptr = malloc(thisSlice);
270  if (ptr == NULL) {clear(); throw std::bad_alloc();}
271  m_data[walk] = (uint8_t*)ptr;
272  }
273  m_size = newSize;
274  }
275  size_t size() const {return m_size;}
276  void clear() {
277  for(size_t walk = 0; walk < m_data.get_size(); ++walk) free(m_data[walk]);
278  m_data.set_size(0);
279  m_size = 0;
280  }
281  void read(void * ptrOut, size_t bytes, size_t offset) {
282  PFC_ASSERT( offset + bytes <= size() );
283  uint8_t * outWalk = (uint8_t*) ptrOut;
284  while(bytes > 0) {
285  size_t o1 = offset / slice, o2 = offset % slice;
286  size_t delta = slice - o2; if (delta > bytes) delta = bytes;
287  memcpy(outWalk, m_data[o1] + o2, delta);
288  offset += delta;
289  bytes -= delta;
290  outWalk += delta;
291  }
292  }
293  void write(const void * ptrIn, size_t bytes, size_t offset) {
294  PFC_ASSERT( offset + bytes <= size() );
295  const uint8_t * inWalk = (const uint8_t*) ptrIn;
296  while(bytes > 0) {
297  size_t o1 = offset / slice, o2 = offset % slice;
298  size_t delta = slice - o2; if (delta > bytes) delta = bytes;
299  memcpy(m_data[o1] + o2, inWalk, delta);
300  offset += delta;
301  bytes -= delta;
302  inWalk += delta;
303  }
304  }
305  uint8_t * _slicePtr(size_t which) {return m_data[which];}
306  size_t _sliceCount() {return m_data.get_size();}
307  size_t _sliceSize(size_t which) {
308  if (which + 1 == _sliceCount()) {
309  size_t s = m_size % slice;
310  if (s) return s;
311  }
312  return slice;
313  }
314  private:
316  size_t m_size;
317 
318  PFC_CLASS_NOT_COPYABLE_EX(bigmem)
319  };
320 
321 
322  double exp_int( double base, int exp );
323 }
324 
325 #endif
sse_control(unsigned p_mask, unsigned p_val)
Definition: other.h:59
void outputDebugLine(const char *msg)
Definition: other.cpp:132
array_t< uint8_t * > m_data
Definition: other.h:315
double exp_int(double base, int exp)
Definition: other.cpp:176
objDestructNotifyScope(objDestructNotify &obj)
Definition: other.h:238
~sse_control()
Definition: other.h:62
t_self & operator>>(t_self &p_dest)
Definition: other.h:142
void write(const void *ptrIn, size_t bytes, size_t offset)
Definition: other.h:293
static const t_instanceList & instanceList()
Definition: other.h:205
static void release(T *p_ptr)
Definition: other.h:80
instanceTrackerV2(const t_self &p_other)
Definition: other.h:200
~bigmem()
Definition: other.h:257
ptrholder_t(const t_self &)
Definition: other.h:116
size_t _sliceCount()
Definition: other.h:306
t_type replace_null_t(t_type &p_var)
Definition: primitives.h:688
size_t _sliceSize(size_t which)
Definition: other.h:307
objDestructNotifyData * m_data
Definition: other.h:233
objDestructNotifyData * m_next
Definition: other.h:217
~fpu_control()
Definition: other.h:31
unsigned old_val
Definition: other.h:23
unsigned mask
Definition: other.h:24
size_t size() const
Definition: other.h:275
static void release(T *p_ptr)
Definition: other.h:84
uint8_t * _slicePtr(size_t which)
Definition: other.h:305
void release()
Definition: other.h:104
unsigned m_oldval
Definition: other.h:66
pfc::avltree_t< TClass * > t_instanceList
Definition: other.h:204
static t_list g_list
Definition: other.h:187
t_self & operator>>(t_self &p_dest)
Definition: other.h:111
instanceTracker< t_base > t_self
Definition: other.h:176
void clear()
Definition: other.h:276
static void release(void *p_ptr)
Definition: other.h:88
ptrholder_t(T *p_ptr)
Definition: other.h:97
instanceTrackerV2< TClass > t_self
Definition: other.h:198
string8_fastalloc string_formatter
Definition: string_base.h:615
bool is_valid() const
Definition: other.h:100
static t_instanceList g_list
Definition: other.h:208
void crash()
Definition: other.cpp:112
fpu_control(unsigned p_mask, unsigned p_val)
Definition: other.h:26
void attach(T *p_ptr)
Definition: other.h:105
void read(void *ptrOut, size_t bytes, size_t offset)
Definition: other.h:281
const t_self & operator=(const t_self &)
Definition: other.h:148
vartoggle_t< bool > booltoggle
Definition: other.h:16
t_self & operator<<(t_self &p_source)
Definition: other.h:141
bool is_empty() const
Definition: other.h:101
t_self & operator<<(t_self &p_source)
Definition: other.h:110
T * get_ptr() const
Definition: other.h:103
const t_self & operator=(const t_self &)
Definition: other.h:117
Assumes t_freefunc to never throw exceptions.
Definition: other.h:93
void resize(size_t newSize)
Definition: other.h:259
pfc::avltree_t< t_self * > t_list
Definition: other.h:183
bigmem()
Definition: other.h:256
T * detach()
Definition: other.h:107
vartoggle_t(T &p_var, const T &val)
Definition: other.h:9
const t_self & operator=(T *p_ptr)
Definition: other.h:138
T & operator*() const
Definition: other.h:108
T * operator->() const
Definition: other.h:102
static const t_list & instanceList()
Definition: other.h:184
size_t m_size
Definition: other.h:316
ptrholder_t< T, t_releaser > t_self
Definition: other.h:127
ptrholder_t< T, t_releaser > t_self
Definition: other.h:95
static void forEach(t_callback &p_callback)
Definition: other.h:185
const t_self & operator=(T *p_ptr)
Definition: other.h:106
static void forEach(t_callback &p_callback)
Definition: other.h:206
instanceTracker(const t_self &p_other)
Definition: other.h:180