Audacity  2.2.2
MemoryX.h
Go to the documentation of this file.
1 #ifndef __AUDACITY_MEMORY_X_H__
2 #define __AUDACITY_MEMORY_X_H__
3 
4 // C++ standard header <memory> with a few extensions
5 #include <memory>
6 #ifndef safenew
7 #define safenew new
8 #endif
9 
10 // Conditional compilation switch indicating whether to rely on
11 // std:: containers knowing about rvalue references
12 #undef __AUDACITY_OLD_STD__
13 
14 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED <= __MAC_10_6
15 
16 #define __AUDACITY_OLD_STD__
17 
18 #include <math.h>
19 inline long long int llrint(float __x) { return __builtin_llrintf(__x); }
20 inline long long int llrint(double __x) { return __builtin_llrintl(__x); }
21 inline long long int llrint(long double __x) { return __builtin_llrintl(__x); }
22 
23 #include <cmath>
24 using std::isnan;
25 using std::isinf;
26 
27 // Need this to define move() and forward()
28 #include <tr1/type_traits>
29 
30 // To define make_shared
31 #include <tr1/memory>
32 
33 // To define function
34 #include <tr1/functional>
35 
36 // To define unordered_set
37 #include <tr1/unordered_set>
38 
39 // To define unordered_map and hash
40 #include <tr1/unordered_map>
41 
42 namespace std {
43  using std::tr1::unordered_set;
44  using std::tr1::hash;
45  using std::tr1::unordered_map;
46  using std::tr1::function;
47  using std::tr1::shared_ptr;
48  using std::tr1::weak_ptr;
49  using std::tr1::static_pointer_cast;
50  using std::tr1::remove_reference;
51  using std::tr1::is_unsigned;
52  using std::tr1::is_const;
53  using std::tr1::add_const;
54  using std::tr1::add_pointer;
55  using std::tr1::remove_pointer;
56 
57  template<typename T> struct add_rvalue_reference {
58  using type = T&&;
59  };
60 
61  template<typename X> struct default_delete
62  {
63  default_delete() {}
64 
65  // Allow copy from other deleter classes
66  template<typename Y>
67  default_delete(const default_delete<Y>& that)
68  {
69  // Break compilation if Y* does not convert to X*
70  // I should figure out the right use of enable_if instead
71  // Note: YPtr avoids bogus compiler warning for C99 compound literals
72  using YPtr = Y*;
73  static_assert((static_cast<X*>(YPtr{}), true),
74  "Pointer types not convertible");
75  }
76 
77  inline void operator() (void *p) const
78  {
79  delete static_cast<X*>(p);
80  }
81  };
82 
83  // Specialization for arrays
84  template<typename X> struct default_delete<X[]>
85  {
86  // Do not allow copy from other deleter classes
87  inline void operator() (void *p) const
88  {
89  delete[] static_cast<X*>(p);
90  }
91  };
92 
93  struct nullptr_t
94  {
95  void* __lx;
96 
97  struct __nat {int __for_bool_;};
98 
99  nullptr_t() : __lx(0) {}
100  nullptr_t(int __nat::*) : __lx(0) {}
101 
102  operator int __nat::*() const {return 0;}
103 
104  template <class _Tp>
105  operator _Tp* () const {return 0;}
106 
107  template <class _Tp, class _Up>
108  operator _Tp _Up::* () const {return 0;}
109 
110  friend bool operator==(nullptr_t, nullptr_t) {return true;}
111  friend bool operator!=(nullptr_t, nullptr_t) {return false;}
112  friend bool operator<(nullptr_t, nullptr_t) {return false;}
113  friend bool operator<=(nullptr_t, nullptr_t) {return true;}
114  friend bool operator>(nullptr_t, nullptr_t) {return false;}
115  friend bool operator>=(nullptr_t, nullptr_t) {return true;}
116  };
117 
118  inline nullptr_t __get_nullptr_t() {return nullptr_t(0);}
119 
120  #define nullptr std::__get_nullptr_t()
121 
122  // "Cast" anything as an rvalue reference.
123  template<typename T> inline typename remove_reference<T>::type&& move(T&& t)
124  { return static_cast<typename std::remove_reference<T>::type&&>(t); }
125 
126  template<typename T, typename D = default_delete<T>> class unique_ptr
127  : private D // use empty base optimization
128  {
129  public:
130  // Default constructor
131  unique_ptr() {}
132 
133  // Implicit constrution from nullptr
134  unique_ptr(nullptr_t) {}
135 
136  // Explicit constructor from pointer and optional deleter
137  explicit unique_ptr(T *p_)
138  : p{ p_ } {}
139  explicit unique_ptr(T *p_, const D &d)
140  : D(d), p{ p_ } {}
141  // Template constructors for upcasting
142  template<typename U>
143  explicit unique_ptr(U* p_)
144  : p{ p_ } {}
145  template<typename U>
146  explicit unique_ptr(U* p_, const D& d)
147  : D(d), p{ p_ } {}
148 
149  // Copy is disallowed
150  unique_ptr(const unique_ptr &) PROHIBITED;
151  unique_ptr& operator= (const unique_ptr &) PROHIBITED;
152 
153  // But move is allowed!
154  unique_ptr(unique_ptr &&that)
155  : D(move(that.get_deleter())), p{ that.release() } { }
156  unique_ptr& operator= (unique_ptr &&that)
157  {
158  if (this != &that) {
159  get_deleter()(p);
160  ((D&)*this) = move(that.get_deleter());
161  p = that.release();
162  }
163  return *this;
164  }
165 
166  // Assign null
167  unique_ptr& operator= (nullptr_t)
168  {
169  get_deleter()(p);
170  p = nullptr;
171  return *this;
172  }
173 
174  // Template versions of move for upcasting
175  template<typename U, typename E>
176  unique_ptr(unique_ptr<U, E> &&that)
177  : D(move(that.get_deleter())), p{ that.release() } { }
178  template<typename U, typename E>
179  unique_ptr& operator= (unique_ptr<U, E> &&that)
180  {
181  // Skip the self-assignment test -- self-assignment should go to the non-template overload
182  get_deleter()(p);
183  p = that.release();
184  get_deleter() = move(that.get_deleter());
185  return *this;
186  }
187 
188  D& get_deleter() { return *this; }
189  const D& get_deleter() const { return *this; }
190 
191  ~unique_ptr() { get_deleter()(p); }
192 
193  T* operator -> () const { return p; }
194  T& operator * () const { return *p; }
195  T* get() const { return p; }
196 
197  // So you can say if(p)
198  explicit operator bool() const { return p != nullptr; }
199 
200  // Give up ownership, don't destroy
201  T* release() { T* result = p; p = nullptr; return result; }
202 
203  void reset(T* __p = nullptr)
204  {
205  T* old__p = p;
206  p = __p;
207  if (old__p != nullptr)
208  {
209  get_deleter()(old__p);
210  }
211  }
212 
213  void swap(unique_ptr& that)
214  {
215  std::swap(p, that.p);
216  std::swap(get_deleter(), that.get_deleter());
217  }
218 
219  private:
220  T *p{};
221  };
222 
223  // Now specialize the class for array types
224  template<typename T, typename D> class unique_ptr<T[], D>
225  : private D // use empty base optimization
226  {
227  public:
228  // Default constructor
229  unique_ptr() {}
230 
231  // Implicit constrution from nullptr
232  unique_ptr(nullptr_t) {}
233 
234  // Explicit constructor from pointer
235  explicit unique_ptr(T *p_)
236  : p{ p_ } {}
237  explicit unique_ptr(T *p_, const D &d)
238  : D( d ), p{ p_ } {}
239  // NO template constructor for upcasting!
240 
241  // Copy is disallowed
242  unique_ptr(const unique_ptr &) PROHIBITED;
243  unique_ptr& operator= (const unique_ptr &)PROHIBITED;
244 
245  // But move is allowed!
246  unique_ptr(unique_ptr &&that)
247  : D( move(that.get_deleter()) ), p{ that.release() } { }
248  unique_ptr& operator= (unique_ptr &&that)
249  {
250  if (this != &that) {
251  get_deleter()(p);
252  p = that.release();
253  ((D&)*this) = move(that.get_deleter());
254  }
255  return *this;
256  }
257 
258  // Assign null
259  unique_ptr& operator= (nullptr_t)
260  {
261  get_deleter()(p);
262  p = nullptr;
263  return *this;
264  }
265 
266  D& get_deleter() { return *this; }
267  const D& get_deleter() const { return *this; }
268 
269  // NO template versions of move for upcasting!
270 
271  ~unique_ptr() { get_deleter()(p); }
272 
273  // No operator ->, but [] instead
274  T& operator [] (size_t n) const { return p[n]; }
275 
276  T& operator * () const { return *p; }
277  T* get() const { return p; }
278 
279  // So you can say if(p)
280  explicit operator bool() const { return p != nullptr; }
281 
282  // Give up ownership, don't destroy
283  T* release() { T* result = p; p = nullptr; return result; }
284 
285  void reset(T* __p = nullptr)
286  {
287  T* old__p = p;
288  p = __p;
289  if (old__p != nullptr)
290  {
291  get_deleter()(old__p);
292  }
293  }
294 
295  void swap(unique_ptr& that)
296  {
297  std::swap(p, that.p);
298  std::swap(get_deleter(), that.get_deleter());
299  }
300 
301  private:
302  T *p{};
303  };
304 
305  // Equality operators for unique_ptr, don't need the specializations for array case
306  template<typename U, typename E>
307  inline bool operator== (nullptr_t, const unique_ptr<U, E>& ptr)
308  {
309  return ptr.get() == nullptr;
310  }
311  template<typename U, typename E>
312  inline bool operator== (const unique_ptr<U, E>& ptr, nullptr_t)
313  {
314  return ptr.get() == nullptr;
315  }
316  template<typename U, typename E, typename V, typename F>
317  inline bool operator == (const unique_ptr<U, E> &ptr1,
318  const unique_ptr<V, F> &ptr2)
319  {
320  return ptr1.get() == ptr2.get();
321  }
322 
323  template<typename U, typename E> inline bool operator != (nullptr_t, const unique_ptr<U, E> &ptr) { return !(ptr == nullptr); }
324  template<typename U, typename E> inline bool operator != (const unique_ptr<U, E> &ptr, nullptr_t) { return !(ptr == nullptr); }
325  template<typename U, typename E, typename V, typename F> inline bool operator != (const unique_ptr<U, E>& ptr1, const unique_ptr<V, F> &ptr2)
326  { return !(ptr1 == ptr2); }
327 
328  // Forward -- pass along rvalue references as rvalue references, anything else as it is
329  // (Because the appropriate overload is taken, and "reference collapse" applies to the return type)
330  template<typename T> inline T&& forward(typename remove_reference<T>::type& t)
331  { return static_cast<T&&>(t); }
332  template<typename T> inline T&& forward(typename remove_reference<T>::type&& t)
333  { return static_cast<T&&>(t); }
334 
335  // Declared but never defined, and typically used in decltype constructs
336  template<typename T>
337  typename std::add_rvalue_reference<T>::type declval() //noexcept
338  ;
339 
340  // We need make_shared for ourselves, because the library doesn't use variadics
341  template<typename X, typename... Args> inline shared_ptr<X> make_shared(Args&&... args)
342  {
343  return shared_ptr<X>{ safenew X(forward<Args>(args)...) };
344  }
345  // From LLVM c++11 and modified
346 
347  #include <cstddef>
348 
349  template<class _Ep>
350  class initializer_list
351  {
352  const _Ep* __begin_;
353  size_t __size_;
354 
355  initializer_list(const _Ep* __b, size_t __s)
356  : __begin_(__b),
357  __size_(__s)
358  {}
359  public:
360  typedef _Ep value_type;
361  typedef const _Ep& reference;
362  typedef const _Ep& const_reference;
363  typedef size_t size_type;
364 
365  typedef const _Ep* iterator;
366  typedef const _Ep* const_iterator;
367 
368  initializer_list() : __begin_(nullptr), __size_(0) {}
369 
370  size_t size() const {return __size_;}
371 
372  const _Ep* begin() const {return __begin_;}
373 
374  const _Ep* end() const {return __begin_ + __size_;}
375  };
376 
377  template<class _Ep>
378  inline
379  const _Ep*
380  begin(initializer_list<_Ep> __il)
381  {
382  return __il.begin();
383  }
384 
385  template<class _Ep>
386  inline
387  const _Ep*
388  end(initializer_list<_Ep> __il)
389  {
390  return __il.end();
391  }
392 }
393 
394 #else
395 
396 // To define function
397 #include <functional>
398 
399 #endif
400 
401 #if !(_MSC_VER >= 1800 || __cplusplus >= 201402L)
402 /* replicate the very useful C++14 make_unique for those build environments
403 that don't implement it yet.
404 typical useage:
405 auto p = std::make_unique<Myclass>(ctorArg1, ctorArg2, ... ctorArgN);
406 p->DoSomething();
407 auto q = std::make_unique<Myclass[]>(count);
408 q[0].DoSomethingElse();
409 
410 The first hides naked NEW and DELETE from the source code.
411 The second hides NEW[] and DELETE[]. Both of course ensure destruction if
412 you don't use something like std::move(p) or q.release(). Both expressions require
413 that you identify the type only once, which is brief and less error prone.
414 
415 (Whereas this omission of [] might invite a runtime error:
416 std::unique_ptr<Myclass> q { safenew Myclass[count] }; )
417 
418 Some C++11 tricks needed here are (1) variadic argument lists and
419 (2) making the compile-time dispatch work correctly. You can't have
420 a partially specialized template function, but you get the effect of that
421 by other metaprogramming means.
422 */
423 
424 namespace std {
425  // For overloading resolution
426  template <typename X> struct __make_unique_result {
427  using scalar_case = unique_ptr<X>;
428  };
429 
430  // Partial specialization of the struct for array case
431  template <typename X> struct __make_unique_result<X[]> {
432  using array_case = unique_ptr<X[]>;
433  using element = X;
434  };
435 
436  // Now the scalar version of unique_ptr
437  template<typename X, typename... Args> inline
439  make_unique(Args&&... args)
440  {
442  { safenew X(forward<Args>(args)...) };
443  }
444 
445  // Now the array version of unique_ptr
446  // The compile-time dispatch trick is that the non-existence
447  // of the scalar_case type makes the above overload
448  // unavailable when the template parameter is explicit
449  template<typename X> inline
450  typename __make_unique_result<X>::array_case
451  make_unique(size_t count)
452  {
453  return typename __make_unique_result<X>::array_case
454  { safenew typename __make_unique_result<X>::element[count] };
455  }
456 }
457 #endif
458 
459 /*
460  * ArrayOf<X>
461  * Not to be confused with std::array (which takes a fixed size) or std::vector
462  * This maintains a pointer allocated by NEW X[]. It's cheap: only one pointer,
463  * with no size and capacity information for resizing as for vector, and if X is
464  * a built-in numeric or pointer type, by default there is no zero filling at
465  * allocation time.
466  */
467 
468 template<typename X>
469 class ArrayOf : public std::unique_ptr<X[]>
470 {
471 public:
472  ArrayOf() {}
473 
474  template<typename Integral>
475  explicit ArrayOf(Integral count, bool initialize = false)
476  {
477  static_assert(std::is_unsigned<Integral>::value, "Unsigned arguments only");
478  reinit(count, initialize);
479  }
480 
481  ArrayOf(const ArrayOf&) PROHIBITED;
482  ArrayOf(ArrayOf&& that)
483  : std::unique_ptr < X[] >
484  (std::move((std::unique_ptr < X[] >&)(that)))
485  {
486  }
488  {
489  std::unique_ptr<X[]>::operator=(std::move(that));
490  return *this;
491  }
492  ArrayOf& operator= (std::unique_ptr<X[]> &&that)
493  {
494  std::unique_ptr<X[]>::operator=(std::move(that));
495  return *this;
496  }
497 
498  template< typename Integral >
499  void reinit(Integral count,
500  bool initialize = false)
501  {
502  static_assert(std::is_unsigned<Integral>::value, "Unsigned arguments only");
503  if (initialize)
504  // Initialize elements (usually, to zero for a numerical type)
505  std::unique_ptr<X[]>::reset(safenew X[count]{});
506  else
507  // Avoid the slight initialization overhead
508  std::unique_ptr<X[]>::reset(safenew X[count]);
509  }
510 };
511 
512 /*
513  * ArraysOf<X>
514  * This simplifies arrays of arrays, each array separately allocated with NEW[]
515  * But it might be better to use std::Array<ArrayOf<X>, N> for some small constant N
516  * Or use just one array when sub-arrays have a common size and are not large.
517  */
518 template<typename X>
519 class ArraysOf : public ArrayOf<ArrayOf<X>>
520 {
521 public:
522  ArraysOf() {}
523 
524  template<typename Integral>
525  explicit ArraysOf(Integral N)
526  : ArrayOf<ArrayOf<X>>( N )
527  {}
528 
529  template<typename Integral1, typename Integral2 >
530  ArraysOf(Integral1 N, Integral2 M, bool initialize = false)
531  : ArrayOf<ArrayOf<X>>( N )
532  {
533  static_assert(std::is_unsigned<Integral1>::value, "Unsigned arguments only");
534  static_assert(std::is_unsigned<Integral2>::value, "Unsigned arguments only");
535  for (size_t ii = 0; ii < N; ++ii)
536  (*this)[ii] = ArrayOf<X>{ M, initialize };
537  }
538 
539  ArraysOf(const ArraysOf&) PROHIBITED;
540  ArraysOf& operator= (ArraysOf&& that)
541  {
542  ArrayOf<ArrayOf<X>>::operator=(std::move(that));
543  return *this;
544  }
545 
546  template< typename Integral >
547  void reinit(Integral count)
548  {
549  ArrayOf<ArrayOf<X>>::reinit( count );
550  }
551 
552  template< typename Integral >
553  void reinit(Integral count, bool initialize)
554  {
555  ArrayOf<ArrayOf<X>>::reinit( count, initialize );
556  }
557 
558  template<typename Integral1, typename Integral2 >
559  void reinit(Integral1 countN, Integral2 countM, bool initialize = false)
560  {
561  static_assert(std::is_unsigned<Integral1>::value, "Unsigned arguments only");
562  static_assert(std::is_unsigned<Integral2>::value, "Unsigned arguments only");
563  reinit(countN, false);
564  for (size_t ii = 0; ii < countN; ++ii)
565  (*this)[ii].reinit(countM, initialize);
566  }
567 };
568 
569 /*
570  * template class Maybe<X>
571  * Can be used for monomorphic objects that are stack-allocable, but only conditionally constructed.
572  * You might also use it as a member.
573  * Initialize with create(), then use like a smart pointer,
574  * with *, ->, get(), reset(), or in if()
575  */
576 
577 // Placement-NEW is used below, and that does not cooperate with the DEBUG_NEW for Visual Studio
578 #ifdef _DEBUG
579 #ifdef _MSC_VER
580 #undef new
581 #endif
582 #endif
583 
584 template<typename X>
585 class Maybe {
586 public:
587 
588  // Construct as NULL
589  Maybe() {}
590 
591  // Supply the copy and move, so you might use this as a class member too
592  Maybe(const Maybe &that)
593  {
594  if (that.get())
595  create(*that);
596  }
597 
598  Maybe& operator= (const Maybe &that)
599  {
600  if (this != &that) {
601  if (that.get())
602  create(*that);
603  else
604  reset();
605  }
606  return *this;
607  }
608 
609  Maybe(Maybe &&that)
610  {
611  if (that.get())
612  create(::std::move(*that));
613  }
614 
616  {
617  if (this != &that) {
618  if (that.get())
619  create(::std::move(*that));
620  else
621  reset();
622  }
623  return *this;
624  }
625 
626  // Make an object in the buffer, passing constructor arguments,
627  // but destroying any previous object first
628  // Note that if constructor throws, we remain in a consistent
629  // NULL state -- giving exception safety but only weakly
630  // (previous value was lost if present)
631  template<typename... Args>
632  void create(Args&&... args)
633  {
634  // Lose any old value
635  reset();
636  // Create NEW value
637  pp = safenew(address()) X(std::forward<Args>(args)...);
638  }
639 
640  // Destroy any object that was built in it
642  {
643  reset();
644  }
645 
646  // Pointer-like operators
647 
648  // Dereference, with the usual bad consequences if NULL
649  X &operator* () const
650  {
651  return *pp;
652  }
653 
654  X *operator-> () const
655  {
656  return pp;
657  }
658 
659  X* get() const
660  {
661  return pp;
662  }
663 
664  void reset()
665  {
666  if (pp)
667  pp->~X(), pp = nullptr;
668  }
669 
670  // So you can say if(ptr)
671  explicit operator bool() const
672  {
673  return pp != nullptr;
674  }
675 
676 private:
677  X* address()
678  {
679  return reinterpret_cast<X*>(&storage);
680  }
681 
682  // Data
683 #if 0
684  typename ::std::aligned_storage<
685  sizeof(X)
686  // , alignof(X) // Not here yet in all compilers
687  >::type storage{};
688 #else
689  union {
690  double d;
691  char storage[sizeof(X)];
692  };
693 #endif
694  X* pp{ nullptr };
695 };
696 
697 // Restore definition of debug new
698 #ifdef _DEBUG
699 #ifdef _MSC_VER
700 #undef THIS_FILE
701 static char*THIS_FILE = __FILE__;
702 #define new new(_NORMAL_BLOCK, THIS_FILE, __LINE__)
703 #endif
704 #endif
705 
706 // Frequently, we need to use a vector or list of unique_ptr if we can, but default
707 // to shared_ptr if we can't (because containers know how to copy elements only,
708 // not move them).
709 #ifdef __AUDACITY_OLD_STD__
710 template<typename T> using movable_ptr = std::shared_ptr<T>;
711 template<typename T, typename Deleter> using movable_ptr_with_deleter_base = std::shared_ptr<T>;
712 #else
713 template<typename T> using movable_ptr = std::unique_ptr<T>;
714 template<typename T, typename Deleter> using movable_ptr_with_deleter_base = std::unique_ptr<T, Deleter>;
715 #endif
716 
717 template<typename T, typename... Args>
718 inline movable_ptr<T> make_movable(Args&&... args)
719 {
720  return std::
721 #ifdef __AUDACITY_OLD_STD__
722  make_shared
723 #else
724  make_unique
725 #endif
726  <T>(std::forward<Args>(args)...);
727 }
728 
729 template<typename T, typename Deleter> class movable_ptr_with_deleter
730  : public movable_ptr_with_deleter_base < T, Deleter >
731 {
732 public:
733  // Do not expose a constructor that takes only a pointer without deleter
734  // That is important when implemented with shared_ptr
736  movable_ptr_with_deleter(T* p, const Deleter &d)
737  : movable_ptr_with_deleter_base<T, Deleter>( p, d ) {}
738 
739 #ifdef __AUDACITY_OLD_STD__
740 
741  // copy
743  : movable_ptr_with_deleter_base < T, Deleter > ( that )
744  {
745  }
746 
748  {
749  if (this != &that) {
751  that;
752  }
753  return *this;
754  }
755 
756 #else
757 
758  // move
760  : movable_ptr_with_deleter_base < T, Deleter > ( std::move(that) )
761  {
762  }
763 
765  {
766  if (this != &that) {
768  std::move(that);
769  }
770  return *this;
771  }
772 
773 #endif
774 };
775 
776 template<typename T, typename Deleter, typename... Args>
778 make_movable_with_deleter(const Deleter &d, Args&&... args)
779 {
780  return movable_ptr_with_deleter<T, Deleter>(safenew T(std::forward<Args>(args)...), d);
781 }
782 
783 /*
784  * A deleter for pointers obtained with malloc
785  */
786 struct freer { void operator() (void *p) const { free(p); } };
787 
788 /*
789  * A useful alias for holding the result of malloc
790  */
791 template< typename T >
792 using MallocPtr = std::unique_ptr< T, freer >;
793 
794 /*
795  * A useful alias for holding the result of strup and similar
796  */
797 template <typename Character = char>
798 using MallocString = std::unique_ptr< Character[], freer >;
799 
800 /*
801  * A deleter class to supply the second template parameter of unique_ptr for
802  * classes like wxWindow that should be sent a message called Destroy rather
803  * than be deleted directly
804  */
805 template <typename T>
806 struct Destroyer {
807  void operator () (T *p) const { if (p) p->Destroy(); }
808 };
809 
810 /*
811  * a convenience for using Destroyer
812  */
813 template <typename T>
814 using Destroy_ptr = std::unique_ptr<T, Destroyer<T>>;
815 
816 /*
817  * "finally" as in The C++ Programming Language, 4th ed., p. 358
818  * Useful for defining ad-hoc RAII actions.
819  * typical usage:
820  * auto cleanup = finally([&]{ ... code; ... });
821  */
822 
823 // Construct this from any copyable function object, such as a lambda
824 template <typename F>
825 struct Final_action {
826  Final_action(F f) : clean( f ) {}
828  F clean;
829 };
830 
831 // Function template with type deduction lets you construct Final_action
832 // without typing any angle brackets
833 template <typename F>
834 Final_action<F> finally (F f)
835 {
836  return Final_action<F>(f);
837 }
838 
839 #include <wx/utils.h> // for wxMin, wxMax
840 #include <algorithm>
841 
842 /*
843  * Set a variable temporarily in a scope
844  */
845 template< typename T >
846 struct RestoreValue {
848  void operator () ( T *p ) const { if (p) *p = oldValue; }
849 };
850 
851 template< typename T >
852 class ValueRestorer : public std::unique_ptr< T, RestoreValue<T> >
853 {
854  using std::unique_ptr< T, RestoreValue<T> >::reset; // make private
855  // But release() remains public and can be useful to commit a changed value
856 public:
857  explicit ValueRestorer( T &var )
858  : std::unique_ptr< T, RestoreValue<T> >( &var, { var } )
859  {}
860  explicit ValueRestorer( T &var, const T& newValue )
861  : std::unique_ptr< T, RestoreValue<T> >( &var, { var } )
862  { var = newValue; }
864  : std::unique_ptr < T, RestoreValue<T> > ( std::move(that) ) {};
866  {
867  if (this != &that)
868  std::unique_ptr < T, RestoreValue<T> >::operator=(std::move(that));
869  return *this;
870  }
871 };
872 
873 // inline functions provide convenient parameter type deduction
874 template< typename T >
876 { return ValueRestorer< T >{ var }; }
877 
878 template< typename T >
879 ValueRestorer< T > valueRestorer( T& var, const T& newValue )
880 { return ValueRestorer< T >{ var, newValue }; }
881 
882 /*
883  * A convenience for use with range-for
884  */
885 template <typename Iterator>
886 struct IteratorRange : public std::pair<Iterator, Iterator> {
887  using iterator = Iterator;
888  using reverse_iterator = std::reverse_iterator<Iterator>;
889 
890  IteratorRange (const Iterator &a, const Iterator &b)
891  : std::pair<Iterator, Iterator> ( a, b ) {}
892 
893  IteratorRange (Iterator &&a, Iterator &&b)
894  : std::pair<Iterator, Iterator> ( std::move(a), std::move(b) ) {}
895 
897  { return { this->rbegin(), this->rend() }; }
898 
899  Iterator begin() const { return this->first; }
900  Iterator end() const { return this->second; }
901 
902  reverse_iterator rbegin() const { return reverse_iterator{ this->second }; }
903  reverse_iterator rend() const { return reverse_iterator{ this->first }; }
904 
905  bool empty() const { return this->begin() == this->end(); }
906  explicit operator bool () const { return !this->empty(); }
907  size_t size() const { return std::distance(this->begin(), this->end()); }
908 
909  template <typename T> iterator find(const T &t) const
910  { return std::find(this->begin(), this->end(), t); }
911 
912  template <typename T> long index(const T &t) const
913  {
914  auto iter = this->find(t);
915  if (iter == this->end())
916  return -1;
917  return std::distance(this->begin(), iter);
918  }
919 
920  template <typename T> bool contains(const T &t) const
921  { return this->end() != this->find(t); }
922 
923  template <typename F> iterator find_if(const F &f) const
924  { return std::find_if(this->begin(), this->end(), f); }
925 
926  template <typename F> long index_if(const F &f) const
927  {
928  auto iter = this->find_if(f);
929  if (iter == this->end())
930  return -1;
931  return std::distance(this->begin(), iter);
932  }
933 
934  // to do: use std::all_of, any_of, none_of when available on all platforms
935  template <typename F> bool all_of(const F &f) const
936  {
937  auto notF =
938  [&](typename std::iterator_traits<Iterator>::reference v)
939  { return !f(v); };
940  return !this->any_of( notF );
941  }
942 
943  template <typename F> bool any_of(const F &f) const
944  { return this->end() != this->find_if(f); }
945 
946  template <typename F> bool none_of(const F &f) const
947  { return !this->any_of(f); }
948 
949  template<typename T> struct identity
950  { const T&& operator () (T &&v) const { return std::forward(v); } };
951 
952  // Like std::accumulate, but the iterators implied, and with another
953  // unary operation on the iterator value, pre-composed
954  template<
955  typename R,
956  typename Binary = std::plus< R >,
957  typename Unary = identity< decltype( *std::declval<Iterator>() ) >
958  >
960  R init,
961  Binary binary_op = {},
962  Unary unary_op = {}
963  ) const
964  {
965  R result = init;
966  for (auto&& v : *this)
967  result = binary_op(result, unary_op(v));
968  return result;
969  }
970 
971  // An overload making it more convenient to use with pointers to member
972  // functions
973  template<
974  typename R,
975  typename Binary = std::plus< R >,
976  typename R2, typename C
977  >
979  R init,
980  Binary binary_op,
981  R2 (C :: * pmf) () const
982  ) const
983  {
984  return this->accumulate( init, binary_op, std::mem_fun( pmf ) );
985  }
986 
987  // Some accumulations frequent enough to be worth abbreviation:
988  template<
989  typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
990  typename R = decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
991  >
992  R min( Unary unary_op = {} ) const
993  {
994  return this->accumulate(
995  std::numeric_limits< R >::max(),
996  (const R&(*)(const R&, const R&)) std::min,
997  unary_op
998  );
999  }
1000 
1001  template<
1002  typename R2, typename C,
1003  typename R = R2
1004  >
1005  R min( R2 (C :: * pmf) () const ) const
1006  {
1007  return this->min( std::mem_fun( pmf ) );
1008  }
1009 
1010  template<
1011  typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
1012  typename R = decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
1013  >
1014  R max( Unary unary_op = {} ) const
1015  {
1016  return this->accumulate(
1017  -std::numeric_limits< R >::max(),
1018  // std::numeric_limits< R >::lowest(), // TODO C++11
1019  (const R&(*)(const R&, const R&)) std::max,
1020  unary_op
1021  );
1022  }
1023 
1024  template<
1025  typename R2, typename C,
1026  typename R = R2
1027  >
1028  R max( R2 (C :: * pmf) () const ) const
1029  {
1030  return this->max( std::mem_fun( pmf ) );
1031  }
1032 
1033  template<
1034  typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
1035  typename R = decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
1036  >
1037  R sum( Unary unary_op = {} ) const
1038  {
1039  return this->accumulate(
1040  R{ 0 },
1041  std::plus< R >{},
1042  unary_op
1043  );
1044  }
1045 
1046  template<
1047  typename R2, typename C,
1048  typename R = R2
1049  >
1050  R sum( R2 (C :: * pmf) () const ) const
1051  {
1052  return this->sum( std::mem_fun( pmf ) );
1053  }
1054 };
1055 
1056 template< typename Iterator>
1058 make_iterator_range( const Iterator &i1, const Iterator &i2 )
1059 {
1060  return { i1, i2 };
1061 }
1062 
1063 template< typename Container >
1065 make_iterator_range( Container &container )
1066 {
1067  return { container.begin(), container.end() };
1068 }
1069 
1070 template< typename Container >
1072 make_iterator_range( const Container &container )
1073 {
1074  return { container.begin(), container.end() };
1075 }
1076 
1077 /*
1078  * Transform an iterator sequence, as another iterator sequence
1079  */
1080 template <
1081  typename Result,
1082  typename Iterator
1083 >
1085  : public std::iterator<
1086  typename std::iterator_traits<Iterator>::iterator_category,
1087  const Result
1088  >
1089 {
1090  // This takes a function on iterators themselves, not on the
1091  // dereference of those iterators, in case you ever need the generality.
1092  using Function = std::function< Result( const Iterator& ) >;
1093 
1094 private:
1095  Iterator mIterator;
1097 
1098 public:
1099  transform_iterator(const Iterator &iterator, const Function &function)
1100  : mIterator( iterator )
1101  , mFunction( function )
1102  {}
1103 
1105  { ++this->mIterator; return *this; }
1107  { auto copy{*this}; ++this->mIterator; return copy; }
1109  { --this->mIterator; return *this; }
1111  { auto copy{*this}; --this->mIterator; return copy; }
1112 
1113  typename transform_iterator::reference operator * ()
1114  { return this->mFunction(this->mIterator); }
1115 
1116  friend inline bool operator == (
1117  const transform_iterator &a, const transform_iterator &b)
1118  { return a.mIterator == b.mIterator; }
1119  friend inline bool operator != (
1120  const transform_iterator &a, const transform_iterator &b)
1121  { return !(a == b); }
1122 };
1123 
1124 template <
1125  typename Iterator,
1126  typename Function
1127 >
1129  decltype( std::declval<Function>() ( std::declval<Iterator>() ) ),
1130  Iterator
1131 >
1132 make_transform_iterator(const Iterator &iterator, Function function)
1133 {
1134  return { iterator, function };
1135 }
1136 
1137 template < typename Function, typename Iterator > struct value_transformer
1138 {
1139  // Adapts a function on values to a function on iterators.
1140  Function function;
1141 
1142  auto operator () (const Iterator &iterator)
1143  -> decltype( function( *iterator ) ) const
1144  { return this->function( *iterator ); }
1145 };
1146 
1147 template <
1148  typename Function,
1149  typename Iterator
1150 >
1152  decltype( std::declval<Function>()( *std::declval<Iterator>() ) ),
1153  Iterator
1154 >;
1155 
1156 template <
1157  typename Function,
1158  typename Iterator
1159 >
1161 make_value_transform_iterator(const Iterator &iterator, Function function)
1162 {
1163  using NewFunction = value_transformer<Function, Iterator>;
1164  return { iterator, NewFunction{ function } };
1165 }
1166 
1167 // For using std::unordered_map on wxString
1168 namespace std
1169 {
1170 #ifdef __AUDACITY_OLD_STD__
1171  namespace tr1
1172  {
1173 #endif
1174  template<typename T> struct hash;
1175  template<> struct hash< wxString > {
1176  size_t operator () (const wxString &str) const // noexcept
1177  {
1178  auto stdstr = str.ToStdWstring(); // no allocations, a cheap fetch
1179  using Hasher = hash< decltype(stdstr) >;
1180  return Hasher{}( stdstr );
1181  }
1182  };
1183 #ifdef __AUDACITY_OLD_STD__
1184  }
1185 #endif
1186 }
1187 
1188 #endif // __AUDACITY_MEMORY_X_H__
Maybe & operator=(const Maybe &that)
Definition: MemoryX.h:598
void operator()(T *p) const
Definition: MemoryX.h:848
R min(R2(C::*pmf)() const ) const
Definition: MemoryX.h:1005
std::function< Result(const Iterator &) > Function
Definition: MemoryX.h:1092
memory.h template class for making an array of arrays.
Definition: MemoryX.h:519
bool contains(const T &t) const
Definition: MemoryX.h:920
reverse_iterator rend() const
Definition: MemoryX.h:903
iterator find(const T &t) const
Definition: MemoryX.h:909
bool operator!=(CommandFlag, unsigned long) PROHIBITED
#define PROHIBITED
Definition: Audacity.h:217
std::unique_ptr< T > movable_ptr
Definition: MemoryX.h:713
reverse_iterator rbegin() const
Definition: MemoryX.h:902
bool operator==(CommandFlag, unsigned long) PROHIBITED
const T && operator()(T &&v) const
Definition: MemoryX.h:950
IteratorRange(Iterator &&a, Iterator &&b)
Definition: MemoryX.h:893
bool none_of(const F &f) const
Definition: MemoryX.h:946
std::unique_ptr< T, Deleter > movable_ptr_with_deleter_base
Definition: MemoryX.h:714
char storage[sizeof(X)]
Definition: MemoryX.h:691
value_transform_iterator< Function, Iterator > make_value_transform_iterator(const Iterator &iterator, Function function)
Definition: MemoryX.h:1161
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:499
X * address()
Definition: MemoryX.h:677
R min(Unary unary_op={}) const
Definition: MemoryX.h:992
ArraysOf(Integral1 N, Integral2 M, bool initialize=false)
Definition: MemoryX.h:530
Iterator mIterator
Definition: MemoryX.h:1095
Final_action(F f)
Definition: MemoryX.h:826
Vector operator*(const Vector &left, const Vector &right)
Definition: Matrix.cpp:153
void reinit(Integral count, bool initialize)
Definition: MemoryX.h:553
~Maybe()
Definition: MemoryX.h:641
movable_ptr_with_deleter(T *p, const Deleter &d)
Definition: MemoryX.h:736
Definition: MemoryX.h:585
ArrayOf & operator=(ArrayOf &&that)
Definition: MemoryX.h:487
R accumulate(R init, Binary binary_op={}, Unary unary_op={}) const
Definition: MemoryX.h:959
friend bool operator==(const transform_iterator &a, const transform_iterator &b)
Definition: MemoryX.h:1116
void reset()
Definition: MemoryX.h:664
IteratorRange< reverse_iterator > reversal() const
Definition: MemoryX.h:896
bool any_of(const F &f) const
Definition: MemoryX.h:943
iterator find_if(const F &f) const
Definition: MemoryX.h:923
movable_ptr< T > make_movable(Args &&...args)
Definition: MemoryX.h:718
std::unique_ptr< Character[], freer > MallocString
Definition: MemoryX.h:798
~Final_action()
Definition: MemoryX.h:827
R accumulate(R init, Binary binary_op, R2(C::*pmf)() const ) const
Definition: MemoryX.h:978
Iterator begin() const
Definition: MemoryX.h:899
ArrayOf(Integral count, bool initialize=false)
Definition: MemoryX.h:475
IteratorRange(const Iterator &a, const Iterator &b)
Definition: MemoryX.h:890
movable_ptr_with_deleter< T, Deleter > make_movable_with_deleter(const Deleter &d, Args &&...args)
Definition: MemoryX.h:778
unique_ptr< X > scalar_case
Definition: MemoryX.h:427
transform_iterator(const Iterator &iterator, const Function &function)
Definition: MemoryX.h:1099
ValueRestorer & operator=(ValueRestorer &&that)
Definition: MemoryX.h:865
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
Definition: MemoryX.h:1058
bool empty() const
Definition: MemoryX.h:905
Maybe(const Maybe &that)
Definition: MemoryX.h:592
R sum(R2(C::*pmf)() const ) const
Definition: MemoryX.h:1050
int min(int a, int b)
X * operator->() const
Definition: MemoryX.h:654
double d
Definition: MemoryX.h:690
transform_iterator< decltype(std::declval< Function >)(std::declval< Iterator >))), Iterator > make_transform_iterator(const Iterator &iterator, Function function)
Definition: MemoryX.h:1132
movable_ptr_with_deleter(movable_ptr_with_deleter &&that)
Definition: MemoryX.h:759
Function mFunction
Definition: MemoryX.h:1096
R sum(Unary unary_op={}) const
Definition: MemoryX.h:1037
movable_ptr_with_deleter & operator=(movable_ptr_with_deleter &&that)
Definition: MemoryX.h:764
ArraysOf(Integral N)
Definition: MemoryX.h:525
X & operator*() const
Definition: MemoryX.h:649
ValueRestorer< T > valueRestorer(T &var)
Definition: MemoryX.h:875
R max(R2(C::*pmf)() const ) const
Definition: MemoryX.h:1028
Definition: MemoryX.h:786
void reinit(Integral count)
Definition: MemoryX.h:547
friend bool operator!=(const transform_iterator &a, const transform_iterator &b)
Definition: MemoryX.h:1119
Memory.h template class for making an array of float, bool, etc.
Definition: MemoryX.h:469
long index(const T &t) const
Definition: MemoryX.h:912
Maybe()
Definition: MemoryX.h:589
transform_iterator & operator--()
Definition: MemoryX.h:1108
transform_iterator & operator++()
Definition: MemoryX.h:1104
long index_if(const F &f) const
Definition: MemoryX.h:926
transform_iterator::reference operator*()
Definition: MemoryX.h:1113
X * get() const
Definition: MemoryX.h:659
std::reverse_iterator< Iterator > reverse_iterator
Definition: MemoryX.h:888
std::unique_ptr< T, Destroyer< T >> Destroy_ptr
Definition: MemoryX.h:814
void operator()(void *p) const
Definition: MemoryX.h:786
ValueRestorer(T &var)
Definition: MemoryX.h:857
Iterator iterator
Definition: MemoryX.h:887
ArraysOf()
Definition: MemoryX.h:522
X * pp
Definition: MemoryX.h:694
bool all_of(const F &f) const
Definition: MemoryX.h:935
unique_ptr< X[]> array_case
Definition: MemoryX.h:432
std::unique_ptr< T, freer > MallocPtr
Definition: MemoryX.h:792
size_t size() const
Definition: MemoryX.h:907
bool operator<(SnapPoint s1, SnapPoint s2)
Definition: Snap.cpp:21
void reinit(Integral1 countN, Integral2 countM, bool initialize=false)
Definition: MemoryX.h:559
R max(Unary unary_op={}) const
Definition: MemoryX.h:1014
void create(Args &&...args)
Definition: MemoryX.h:632
#define safenew
Definition: MemoryX.h:7
void operator()(T *p) const
Definition: MemoryX.h:807
auto operator()(const Iterator &iterator) -> decltype(function(*iterator)) const
Definition: MemoryX.h:1142
Iterator end() const
Definition: MemoryX.h:900
Maybe(Maybe &&that)
Definition: MemoryX.h:609
ArrayOf()
Definition: MemoryX.h:472