Audacity  2.2.0
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 
7 #ifndef safenew
8 #define safenew new
9 #endif
10 
11 // Conditional compilation switch indicating whether to rely on
12 // std:: containers knowing about rvalue references
13 #undef __AUDACITY_OLD_STD__
14 
15 #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED <= __MAC_10_6
16 
17 #define __AUDACITY_OLD_STD__
18 
19 #include <math.h>
20 inline long long int llrint(float __x) { return __builtin_llrintf(__x); }
21 inline long long int llrint(double __x) { return __builtin_llrintl(__x); }
22 inline long long int llrint(long double __x) { return __builtin_llrintl(__x); }
23 
24 #include <cmath>
25 using std::isnan;
26 using std::isinf;
27 
28 // Need this to define move() and forward()
29 #include <tr1/type_traits>
30 
31 // To define make_shared
32 #include <tr1/memory>
33 
34 namespace std {
35  using std::tr1::shared_ptr;
36  using std::tr1::weak_ptr;
37  using std::tr1::static_pointer_cast;
38  using std::tr1::remove_reference;
39  using std::tr1::is_unsigned;
40 
41  template<typename X> struct default_delete
42  {
43  default_delete() {}
44 
45  // Allow copy from other deleter classes
46  template<typename Y>
47  default_delete(const default_delete<Y>& that)
48  {
49  // Break compilation if Y* does not convert to X*
50  // I should figure out the right use of enable_if instead
51  // Note: YPtr avoids bogus compiler warning for C99 compound literals
52  using YPtr = Y*;
53  static_assert((static_cast<X*>(YPtr{}), true),
54  "Pointer types not convertible");
55  }
56 
57  inline void operator() (void *p) const
58  {
59  delete static_cast<X*>(p);
60  }
61  };
62 
63  // Specialization for arrays
64  template<typename X> struct default_delete<X[]>
65  {
66  // Do not allow copy from other deleter classes
67  inline void operator() (void *p) const
68  {
69  delete[] static_cast<X*>(p);
70  }
71  };
72 
73  struct nullptr_t
74  {
75  void* __lx;
76 
77  struct __nat {int __for_bool_;};
78 
79  nullptr_t() : __lx(0) {}
80  nullptr_t(int __nat::*) : __lx(0) {}
81 
82  operator int __nat::*() const {return 0;}
83 
84  template <class _Tp>
85  operator _Tp* () const {return 0;}
86 
87  template <class _Tp, class _Up>
88  operator _Tp _Up::* () const {return 0;}
89 
90  friend bool operator==(nullptr_t, nullptr_t) {return true;}
91  friend bool operator!=(nullptr_t, nullptr_t) {return false;}
92  friend bool operator<(nullptr_t, nullptr_t) {return false;}
93  friend bool operator<=(nullptr_t, nullptr_t) {return true;}
94  friend bool operator>(nullptr_t, nullptr_t) {return false;}
95  friend bool operator>=(nullptr_t, nullptr_t) {return true;}
96  };
97 
98  inline nullptr_t __get_nullptr_t() {return nullptr_t(0);}
99 
100  #define nullptr std::__get_nullptr_t()
101 
102  // "Cast" anything as an rvalue reference.
103  template<typename T> inline typename remove_reference<T>::type&& move(T&& t)
104  { return static_cast<typename std::remove_reference<T>::type&&>(t); }
105 
106  template<typename T, typename D = default_delete<T>> class unique_ptr
107  : private D // use empty base optimization
108  {
109  public:
110  // Default constructor
111  unique_ptr() {}
112 
113  // Implicit constrution from nullptr
114  unique_ptr(nullptr_t) {}
115 
116  // Explicit constructor from pointer and optional deleter
117  explicit unique_ptr(T *p_)
118  : p{ p_ } {}
119  explicit unique_ptr(T *p_, const D &d)
120  : D(d), p{ p_ } {}
121  // Template constructors for upcasting
122  template<typename U>
123  explicit unique_ptr(U* p_)
124  : p{ p_ } {}
125  template<typename U>
126  explicit unique_ptr(U* p_, const D& d)
127  : D(d), p{ p_ } {}
128 
129  // Copy is disallowed
130  unique_ptr(const unique_ptr &) PROHIBITED;
131  unique_ptr& operator= (const unique_ptr &) PROHIBITED;
132 
133  // But move is allowed!
134  unique_ptr(unique_ptr &&that)
135  : D(move(that.get_deleter())), p{ that.release() } { }
136  unique_ptr& operator= (unique_ptr &&that)
137  {
138  if (this != &that) {
139  get_deleter()(p);
140  ((D&)*this) = move(that.get_deleter());
141  p = that.release();
142  }
143  return *this;
144  }
145 
146  // Assign null
147  unique_ptr& operator= (nullptr_t)
148  {
149  get_deleter()(p);
150  p = nullptr;
151  return *this;
152  }
153 
154  // Template versions of move for upcasting
155  template<typename U, typename E>
156  unique_ptr(unique_ptr<U, E> &&that)
157  : D(move(that.get_deleter())), p{ that.release() } { }
158  template<typename U, typename E>
159  unique_ptr& operator= (unique_ptr<U, E> &&that)
160  {
161  // Skip the self-assignment test -- self-assignment should go to the non-template overload
162  get_deleter()(p);
163  p = that.release();
164  get_deleter() = move(that.get_deleter());
165  return *this;
166  }
167 
168  D& get_deleter() { return *this; }
169  const D& get_deleter() const { return *this; }
170 
171  ~unique_ptr() { get_deleter()(p); }
172 
173  T* operator -> () const { return p; }
174  T& operator * () const { return *p; }
175  T* get() const { return p; }
176 
177  // So you can say if(p)
178  explicit operator bool() const { return p != nullptr; }
179 
180  // Give up ownership, don't destroy
181  T* release() { T* result = p; p = nullptr; return result; }
182 
183  void reset(T* __p = nullptr)
184  {
185  T* old__p = p;
186  p = __p;
187  if (old__p != nullptr)
188  {
189  get_deleter()(old__p);
190  }
191  }
192 
193  void swap(unique_ptr& that)
194  {
195  std::swap(p, that.p);
196  std::swap(get_deleter(), that.get_deleter());
197  }
198 
199  private:
200  T *p{};
201  };
202 
203  // Now specialize the class for array types
204  template<typename T, typename D> class unique_ptr<T[], D>
205  : private D // use empty base optimization
206  {
207  public:
208  // Default constructor
209  unique_ptr() {}
210 
211  // Implicit constrution from nullptr
212  unique_ptr(nullptr_t) {}
213 
214  // Explicit constructor from pointer
215  explicit unique_ptr(T *p_)
216  : p{ p_ } {}
217  explicit unique_ptr(T *p_, const D &d)
218  : D( d ), p{ p_ } {}
219  // NO template constructor for upcasting!
220 
221  // Copy is disallowed
222  unique_ptr(const unique_ptr &) PROHIBITED;
223  unique_ptr& operator= (const unique_ptr &)PROHIBITED;
224 
225  // But move is allowed!
226  unique_ptr(unique_ptr &&that)
227  : D( move(that.get_deleter()) ), p{ that.release() } { }
228  unique_ptr& operator= (unique_ptr &&that)
229  {
230  if (this != &that) {
231  get_deleter()(p);
232  p = that.release();
233  ((D&)*this) = move(that.get_deleter());
234  }
235  return *this;
236  }
237 
238  // Assign null
239  unique_ptr& operator= (nullptr_t)
240  {
241  get_deleter()(p);
242  p = nullptr;
243  return *this;
244  }
245 
246  D& get_deleter() { return *this; }
247  const D& get_deleter() const { return *this; }
248 
249  // NO template versions of move for upcasting!
250 
251  ~unique_ptr() { get_deleter()(p); }
252 
253  // No operator ->, but [] instead
254  T& operator [] (size_t n) const { return p[n]; }
255 
256  T& operator * () const { return *p; }
257  T* get() const { return p; }
258 
259  // So you can say if(p)
260  explicit operator bool() const { return p != nullptr; }
261 
262  // Give up ownership, don't destroy
263  T* release() { T* result = p; p = nullptr; return result; }
264 
265  void reset(T* __p = nullptr)
266  {
267  T* old__p = p;
268  p = __p;
269  if (old__p != nullptr)
270  {
271  get_deleter()(old__p);
272  }
273  }
274 
275  void swap(unique_ptr& that)
276  {
277  std::swap(p, that.p);
278  std::swap(get_deleter(), that.get_deleter());
279  }
280 
281  private:
282  T *p{};
283  };
284 
285  // Equality operators for unique_ptr, don't need the specializations for array case
286  template<typename U, typename E>
287  inline bool operator== (nullptr_t, const unique_ptr<U, E>& ptr)
288  {
289  return ptr.get() == nullptr;
290  }
291  template<typename U, typename E>
292  inline bool operator== (const unique_ptr<U, E>& ptr, nullptr_t)
293  {
294  return ptr.get() == nullptr;
295  }
296  template<typename U, typename E, typename V, typename F>
297  inline bool operator == (const unique_ptr<U, E> &ptr1,
298  const unique_ptr<V, F> &ptr2)
299  {
300  return ptr1.get() == ptr2.get();
301  }
302 
303  template<typename U, typename E> inline bool operator != (nullptr_t, const unique_ptr<U, E> &ptr) { return !(ptr == nullptr); }
304  template<typename U, typename E> inline bool operator != (const unique_ptr<U, E> &ptr, nullptr_t) { return !(ptr == nullptr); }
305  template<typename U, typename E, typename V, typename F> inline bool operator != (const unique_ptr<U, E>& ptr1, const unique_ptr<V, F> &ptr2)
306  { return !(ptr1 == ptr2); }
307 
308  // Forward -- pass along rvalue references as rvalue references, anything else as it is
309  // (Because the appropriate overload is taken, and "reference collapse" applies to the return type)
310  template<typename T> inline T&& forward(typename remove_reference<T>::type& t)
311  { return static_cast<T&&>(t); }
312  template<typename T> inline T&& forward(typename remove_reference<T>::type&& t)
313  { return static_cast<T&&>(t); }
314 
315  // We need make_shared for ourselves, because the library doesn't use variadics
316  template<typename X, typename... Args> inline shared_ptr<X> make_shared(Args&&... args)
317  {
318  return shared_ptr<X>{ safenew X(forward<Args>(args)...) };
319  }
320  // From LLVM c++11 and modified
321 
322  #include <cstddef>
323 
324  template<class _Ep>
325  class initializer_list
326  {
327  const _Ep* __begin_;
328  size_t __size_;
329 
330  initializer_list(const _Ep* __b, size_t __s)
331  : __begin_(__b),
332  __size_(__s)
333  {}
334  public:
335  typedef _Ep value_type;
336  typedef const _Ep& reference;
337  typedef const _Ep& const_reference;
338  typedef size_t size_type;
339 
340  typedef const _Ep* iterator;
341  typedef const _Ep* const_iterator;
342 
343  initializer_list() : __begin_(nullptr), __size_(0) {}
344 
345  size_t size() const {return __size_;}
346 
347  const _Ep* begin() const {return __begin_;}
348 
349  const _Ep* end() const {return __begin_ + __size_;}
350  };
351 
352  template<class _Ep>
353  inline
354  const _Ep*
355  begin(initializer_list<_Ep> __il)
356  {
357  return __il.begin();
358  }
359 
360  template<class _Ep>
361  inline
362  const _Ep*
363  end(initializer_list<_Ep> __il)
364  {
365  return __il.end();
366  }
367 }
368 
369 #endif
370 
371 #if !(_MSC_VER >= 1800 || __cplusplus >= 201402L)
372 /* replicate the very useful C++14 make_unique for those build environments
373 that don't implement it yet.
374 typical useage:
375 auto p = std::make_unique<Myclass>(ctorArg1, ctorArg2, ... ctorArgN);
376 p->DoSomething();
377 auto q = std::make_unique<Myclass[]>(count);
378 q[0].DoSomethingElse();
379 
380 The first hides naked NEW and DELETE from the source code.
381 The second hides NEW[] and DELETE[]. Both of course ensure destruction if
382 you don't use something like std::move(p) or q.release(). Both expressions require
383 that you identify the type only once, which is brief and less error prone.
384 
385 (Whereas this omission of [] might invite a runtime error:
386 std::unique_ptr<Myclass> q { safenew Myclass[count] }; )
387 
388 Some C++11 tricks needed here are (1) variadic argument lists and
389 (2) making the compile-time dispatch work correctly. You can't have
390 a partially specialized template function, but you get the effect of that
391 by other metaprogramming means.
392 */
393 
394 namespace std {
395  // For overloading resolution
396  template <typename X> struct __make_unique_result {
397  using scalar_case = unique_ptr<X>;
398  };
399 
400  // Partial specialization of the struct for array case
401  template <typename X> struct __make_unique_result<X[]> {
402  using array_case = unique_ptr<X[]>;
403  using element = X;
404  };
405 
406  // Now the scalar version of unique_ptr
407  template<typename X, typename... Args> inline
409  make_unique(Args&&... args)
410  {
412  { safenew X(forward<Args>(args)...) };
413  }
414 
415  // Now the array version of unique_ptr
416  // The compile-time dispatch trick is that the non-existence
417  // of the scalar_case type makes the above overload
418  // unavailable when the template parameter is explicit
419  template<typename X> inline
420  typename __make_unique_result<X>::array_case
421  make_unique(size_t count)
422  {
423  return typename __make_unique_result<X>::array_case
424  { safenew typename __make_unique_result<X>::element[count] };
425  }
426 }
427 #endif
428 
429 /*
430  * ArrayOf<X>
431  * Not to be confused with std::array (which takes a fixed size) or std::vector
432  * This maintains a pointer allocated by NEW X[]. It's cheap: only one pointer,
433  * with no size and capacity information for resizing as for vector, and if X is
434  * a built-in numeric or pointer type, by default there is no zero filling at
435  * allocation time.
436  */
437 
438 template<typename X>
439 class ArrayOf : public std::unique_ptr<X[]>
440 {
441 public:
442  ArrayOf() {}
443 
444  template<typename Integral>
445  explicit ArrayOf(Integral count, bool initialize = false)
446  {
447  static_assert(std::is_unsigned<Integral>::value, "Unsigned arguments only");
448  reinit(count, initialize);
449  }
450 
451  ArrayOf(const ArrayOf&) PROHIBITED;
452  ArrayOf(ArrayOf&& that)
453  : std::unique_ptr < X[] >
454  (std::move((std::unique_ptr < X[] >&)(that)))
455  {
456  }
458  {
459  std::unique_ptr<X[]>::operator=(std::move(that));
460  return *this;
461  }
462  ArrayOf& operator= (std::unique_ptr<X[]> &&that)
463  {
464  std::unique_ptr<X[]>::operator=(std::move(that));
465  return *this;
466  }
467 
468  template< typename Integral >
469  void reinit(Integral count,
470  bool initialize = false)
471  {
472  static_assert(std::is_unsigned<Integral>::value, "Unsigned arguments only");
473  if (initialize)
474  // Initialize elements (usually, to zero for a numerical type)
475  std::unique_ptr<X[]>::reset(safenew X[count]{});
476  else
477  // Avoid the slight initialization overhead
478  std::unique_ptr<X[]>::reset(safenew X[count]);
479  }
480 };
481 
482 /*
483  * ArraysOf<X>
484  * This simplifies arrays of arrays, each array separately allocated with NEW[]
485  * But it might be better to use std::Array<ArrayOf<X>, N> for some small constant N
486  * Or use just one array when sub-arrays have a common size and are not large.
487  */
488 template<typename X>
489 class ArraysOf : public ArrayOf<ArrayOf<X>>
490 {
491 public:
492  ArraysOf() {}
493 
494  template<typename Integral>
495  explicit ArraysOf(Integral N)
496  : ArrayOf<ArrayOf<X>>( N )
497  {}
498 
499  template<typename Integral1, typename Integral2 >
500  ArraysOf(Integral1 N, Integral2 M, bool initialize = false)
501  : ArrayOf<ArrayOf<X>>( N )
502  {
503  static_assert(std::is_unsigned<Integral1>::value, "Unsigned arguments only");
504  static_assert(std::is_unsigned<Integral2>::value, "Unsigned arguments only");
505  for (size_t ii = 0; ii < N; ++ii)
506  (*this)[ii] = ArrayOf<X>{ M, initialize };
507  }
508 
509  ArraysOf(const ArraysOf&) PROHIBITED;
510  ArraysOf& operator= (ArraysOf&& that)
511  {
512  ArrayOf<ArrayOf<X>>::operator=(std::move(that));
513  return *this;
514  }
515 
516  template< typename Integral >
517  void reinit(Integral count)
518  {
519  ArrayOf<ArrayOf<X>>::reinit( count );
520  }
521 
522  template< typename Integral >
523  void reinit(Integral count, bool initialize)
524  {
525  ArrayOf<ArrayOf<X>>::reinit( count, initialize );
526  }
527 
528  template<typename Integral1, typename Integral2 >
529  void reinit(Integral1 countN, Integral2 countM, bool initialize = false)
530  {
531  static_assert(std::is_unsigned<Integral1>::value, "Unsigned arguments only");
532  static_assert(std::is_unsigned<Integral2>::value, "Unsigned arguments only");
533  reinit(countN, false);
534  for (size_t ii = 0; ii < countN; ++ii)
535  (*this)[ii].reinit(countM, initialize);
536  }
537 };
538 
539 /*
540  * template class Maybe<X>
541  * Can be used for monomorphic objects that are stack-allocable, but only conditionally constructed.
542  * You might also use it as a member.
543  * Initialize with create(), then use like a smart pointer,
544  * with *, ->, get(), reset(), or in if()
545  */
546 
547 // Placement-NEW is used below, and that does not cooperate with the DEBUG_NEW for Visual Studio
548 #ifdef _DEBUG
549 #ifdef _MSC_VER
550 #undef new
551 #endif
552 #endif
553 
554 template<typename X>
555 class Maybe {
556 public:
557 
558  // Construct as NULL
559  Maybe() {}
560 
561  // Supply the copy and move, so you might use this as a class member too
562  Maybe(const Maybe &that)
563  {
564  if (that.get())
565  create(*that);
566  }
567 
568  Maybe& operator= (const Maybe &that)
569  {
570  if (this != &that) {
571  if (that.get())
572  create(*that);
573  else
574  reset();
575  }
576  return *this;
577  }
578 
579  Maybe(Maybe &&that)
580  {
581  if (that.get())
582  create(::std::move(*that));
583  }
584 
586  {
587  if (this != &that) {
588  if (that.get())
589  create(::std::move(*that));
590  else
591  reset();
592  }
593  return *this;
594  }
595 
596  // Make an object in the buffer, passing constructor arguments,
597  // but destroying any previous object first
598  // Note that if constructor throws, we remain in a consistent
599  // NULL state -- giving exception safety but only weakly
600  // (previous value was lost if present)
601  template<typename... Args>
602  void create(Args&&... args)
603  {
604  // Lose any old value
605  reset();
606  // Create NEW value
607  pp = safenew(address()) X(std::forward<Args>(args)...);
608  }
609 
610  // Destroy any object that was built in it
612  {
613  reset();
614  }
615 
616  // Pointer-like operators
617 
618  // Dereference, with the usual bad consequences if NULL
619  X &operator* () const
620  {
621  return *pp;
622  }
623 
624  X *operator-> () const
625  {
626  return pp;
627  }
628 
629  X* get() const
630  {
631  return pp;
632  }
633 
634  void reset()
635  {
636  if (pp)
637  pp->~X(), pp = nullptr;
638  }
639 
640  // So you can say if(ptr)
641  explicit operator bool() const
642  {
643  return pp != nullptr;
644  }
645 
646 private:
647  X* address()
648  {
649  return reinterpret_cast<X*>(&storage);
650  }
651 
652  // Data
653 #if 0
654  typename ::std::aligned_storage<
655  sizeof(X)
656  // , alignof(X) // Not here yet in all compilers
657  >::type storage{};
658 #else
659  union {
660  double d;
661  char storage[sizeof(X)];
662  };
663 #endif
664  X* pp{ nullptr };
665 };
666 
667 // Restore definition of debug new
668 #ifdef _DEBUG
669 #ifdef _MSC_VER
670 #undef THIS_FILE
671 static char*THIS_FILE = __FILE__;
672 #define new new(_NORMAL_BLOCK, THIS_FILE, __LINE__)
673 #endif
674 #endif
675 
676 // Frequently, we need to use a vector or list of unique_ptr if we can, but default
677 // to shared_ptr if we can't (because containers know how to copy elements only,
678 // not move them).
679 #ifdef __AUDACITY_OLD_STD__
680 template<typename T> using movable_ptr = std::shared_ptr<T>;
681 template<typename T, typename Deleter> using movable_ptr_with_deleter_base = std::shared_ptr<T>;
682 #else
683 template<typename T> using movable_ptr = std::unique_ptr<T>;
684 template<typename T, typename Deleter> using movable_ptr_with_deleter_base = std::unique_ptr<T, Deleter>;
685 #endif
686 
687 template<typename T, typename... Args>
688 inline movable_ptr<T> make_movable(Args&&... args)
689 {
690  return std::
691 #ifdef __AUDACITY_OLD_STD__
692  make_shared
693 #else
694  make_unique
695 #endif
696  <T>(std::forward<Args>(args)...);
697 }
698 
699 template<typename T, typename Deleter> class movable_ptr_with_deleter
700  : public movable_ptr_with_deleter_base < T, Deleter >
701 {
702 public:
703  // Do not expose a constructor that takes only a pointer without deleter
704  // That is important when implemented with shared_ptr
706  movable_ptr_with_deleter(T* p, const Deleter &d)
707  : movable_ptr_with_deleter_base<T, Deleter>( p, d ) {}
708 
709 #ifdef __AUDACITY_OLD_STD__
710 
711  // copy
713  : movable_ptr_with_deleter_base < T, Deleter > ( that )
714  {
715  }
716 
718  {
719  if (this != &that) {
721  that;
722  }
723  return *this;
724  }
725 
726 #else
727 
728  // move
730  : movable_ptr_with_deleter_base < T, Deleter > ( std::move(that) )
731  {
732  }
733 
735  {
736  if (this != &that) {
738  std::move(that);
739  }
740  return *this;
741  }
742 
743 #endif
744 };
745 
746 template<typename T, typename Deleter, typename... Args>
748 make_movable_with_deleter(const Deleter &d, Args&&... args)
749 {
750  return movable_ptr_with_deleter<T, Deleter>(safenew T(std::forward<Args>(args)...), d);
751 }
752 
753 /*
754  * A deleter for pointers obtained with malloc
755  */
756 struct freer { void operator() (void *p) const { free(p); } };
757 
758 /*
759  * A useful alias for holding the result of malloc
760  */
761 template< typename T >
762 using MallocPtr = std::unique_ptr< T, freer >;
763 
764 /*
765  * A useful alias for holding the result of strup and similar
766  */
767 template <typename Character = char>
768 using MallocString = std::unique_ptr< Character[], freer >;
769 
770 /*
771  * A deleter class to supply the second template parameter of unique_ptr for
772  * classes like wxWindow that should be sent a message called Destroy rather
773  * than be deleted directly
774  */
775 template <typename T>
776 struct Destroyer {
777  void operator () (T *p) const { if (p) p->Destroy(); }
778 };
779 
780 /*
781  * a convenience for using Destroyer
782  */
783 template <typename T>
784 using Destroy_ptr = std::unique_ptr<T, Destroyer<T>>;
785 
786 /*
787  * "finally" as in The C++ Programming Language, 4th ed., p. 358
788  * Useful for defining ad-hoc RAII actions.
789  * typical usage:
790  * auto cleanup = finally([&]{ ... code; ... });
791  */
792 
793 // Construct this from any copyable function object, such as a lambda
794 template <typename F>
795 struct Final_action {
796  Final_action(F f) : clean( f ) {}
798  F clean;
799 };
800 
801 // Function template with type deduction lets you construct Final_action
802 // without typing any angle brackets
803 template <typename F>
804 Final_action<F> finally (F f)
805 {
806  return Final_action<F>(f);
807 }
808 
809 /*
810  * Set a variable temporarily in a scope
811  */
812 template< typename T >
813 struct RestoreValue {
815  void operator () ( T *p ) const { if (p) *p = oldValue; }
816 };
817 
818 template< typename T >
819 class ValueRestorer : public std::unique_ptr< T, RestoreValue<T> >
820 {
821  using std::unique_ptr< T, RestoreValue<T> >::reset; // make private
822  // But release() remains public and can be useful to commit a changed value
823 public:
824  explicit ValueRestorer( T &var )
825  : std::unique_ptr< T, RestoreValue<T> >( &var, { var } )
826  {}
827  explicit ValueRestorer( T &var, const T& newValue )
828  : std::unique_ptr< T, RestoreValue<T> >( &var, { var } )
829  { var = newValue; }
831  : std::unique_ptr < T, RestoreValue<T> > ( std::move(that) ) {};
833  {
834  if (this != &that)
835  std::unique_ptr < T, RestoreValue<T> >::operator=(std::move(that));
836  return *this;
837  }
838 };
839 
840 // inline functions provide convenient parameter type deduction
841 template< typename T >
843 { return ValueRestorer< T >{ var }; }
844 
845 template< typename T >
846 ValueRestorer< T > valueRestorer( T& var, const T& newValue )
847 { return ValueRestorer< T >{ var, newValue }; }
848 
849 /*
850  * A convenience for use with range-for
851  */
852 template <typename Iterator>
853 struct IteratorRange : public std::pair<Iterator, Iterator> {
854  IteratorRange (Iterator &&a, Iterator &&b)
855  : std::pair<Iterator, Iterator> ( std::move(a), std::move(b) ) {}
856 
857  Iterator begin() const { return this->first; }
858  Iterator end() const { return this->second; }
859 };
860 
861 #endif // __AUDACITY_MEMORY_X_H__
Maybe & operator=(const Maybe &that)
Definition: MemoryX.h:568
void operator()(T *p) const
Definition: MemoryX.h:815
memory.h template class for making an array of arrays.
Definition: MemoryX.h:489
bool operator!=(CommandFlag, unsigned long) PROHIBITED
#define PROHIBITED
Definition: Audacity.h:248
std::unique_ptr< T > movable_ptr
Definition: MemoryX.h:683
bool operator==(CommandFlag, unsigned long) PROHIBITED
IteratorRange(Iterator &&a, Iterator &&b)
Definition: MemoryX.h:854
std::unique_ptr< T, Deleter > movable_ptr_with_deleter_base
Definition: MemoryX.h:684
char storage[sizeof(X)]
Definition: MemoryX.h:661
void reinit(Integral count, bool initialize=false)
Definition: MemoryX.h:469
X * address()
Definition: MemoryX.h:647
ArraysOf(Integral1 N, Integral2 M, bool initialize=false)
Definition: MemoryX.h:500
Final_action(F f)
Definition: MemoryX.h:796
Vector operator*(const Vector &left, const Vector &right)
Definition: Matrix.cpp:153
void reinit(Integral count, bool initialize)
Definition: MemoryX.h:523
Definition: MemoryX.h:699
~Maybe()
Definition: MemoryX.h:611
movable_ptr_with_deleter(T *p, const Deleter &d)
Definition: MemoryX.h:706
Definition: MemoryX.h:555
Definition: MemoryX.h:853
ArrayOf & operator=(ArrayOf &&that)
Definition: MemoryX.h:457
Definition: MemoryX.h:795
void reset()
Definition: MemoryX.h:634
movable_ptr< T > make_movable(Args &&...args)
Definition: MemoryX.h:688
std::unique_ptr< Character[], freer > MallocString
Definition: MemoryX.h:768
~Final_action()
Definition: MemoryX.h:797
Iterator begin() const
Definition: MemoryX.h:857
ArrayOf(Integral count, bool initialize=false)
Definition: MemoryX.h:445
movable_ptr_with_deleter< T, Deleter > make_movable_with_deleter(const Deleter &d, Args &&...args)
Definition: MemoryX.h:748
unique_ptr< X > scalar_case
Definition: MemoryX.h:397
Definition: MemoryX.h:813
ValueRestorer & operator=(ValueRestorer &&that)
Definition: MemoryX.h:832
T oldValue
Definition: MemoryX.h:814
X element
Definition: MemoryX.h:403
Maybe(const Maybe &that)
Definition: MemoryX.h:562
X * operator->() const
Definition: MemoryX.h:624
Definition: MemoryX.h:776
double d
Definition: MemoryX.h:660
movable_ptr_with_deleter()
Definition: MemoryX.h:705
movable_ptr_with_deleter(movable_ptr_with_deleter &&that)
Definition: MemoryX.h:729
Definition: MemoryX.h:396
movable_ptr_with_deleter & operator=(movable_ptr_with_deleter &&that)
Definition: MemoryX.h:734
F clean
Definition: MemoryX.h:798
ArraysOf(Integral N)
Definition: MemoryX.h:495
X & operator*() const
Definition: MemoryX.h:619
ValueRestorer< T > valueRestorer(T &var)
Definition: MemoryX.h:842
Definition: MemoryX.h:756
void reinit(Integral count)
Definition: MemoryX.h:517
Definition: MemoryX.h:819
Memory.h template class for making an array of float, bool, etc.
Definition: MemoryX.h:439
Maybe()
Definition: MemoryX.h:559
X * get() const
Definition: MemoryX.h:629
std::unique_ptr< T, Destroyer< T >> Destroy_ptr
Definition: MemoryX.h:784
void operator()(void *p) const
Definition: MemoryX.h:756
ValueRestorer(T &var)
Definition: MemoryX.h:824
ArraysOf()
Definition: MemoryX.h:492
X * pp
Definition: MemoryX.h:664
unique_ptr< X[]> array_case
Definition: MemoryX.h:402
std::unique_ptr< T, freer > MallocPtr
Definition: MemoryX.h:762
bool operator<(SnapPoint s1, SnapPoint s2)
Definition: Snap.cpp:23
void reinit(Integral1 countN, Integral2 countM, bool initialize=false)
Definition: MemoryX.h:529
void create(Args &&...args)
Definition: MemoryX.h:602
#define safenew
Definition: MemoryX.h:8
void operator()(T *p) const
Definition: MemoryX.h:777
Iterator end() const
Definition: MemoryX.h:858
Maybe(Maybe &&that)
Definition: MemoryX.h:579
ArrayOf()
Definition: MemoryX.h:442