mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-10 16:43:33 +02:00
Replicated C++11 library things no longer needed
This commit is contained in:
402
src/MemoryX.h
402
src/MemoryX.h
@@ -13,410 +13,8 @@
|
||||
#undef __AUDACITY_OLD_STD__
|
||||
|
||||
|
||||
// JKC:
|
||||
// This is completely the wrong way to test for new stdlib (supporting std::hash etc)
|
||||
// We should instead use configure checks or test if __cplusplus is bigger that some value.
|
||||
//
|
||||
// On the other hand, as we are moving to wxWidgets 3.1.1, macOSX 10.7+ is required.
|
||||
// And we could just assume/require building with C++11 and remove the body of this
|
||||
// ifdef - i.e. no longer support those workarounds.
|
||||
//
|
||||
// Macports have provided some really useful information about possibilities for
|
||||
// building with newer compilers and older SDKs. So the option of building with old
|
||||
// compilers and old SDKs may not be needed at all, making the shift to requiring
|
||||
// C++11 have little to no downside. So as of 13th April 2018 the code in this
|
||||
// ifdef's days are numbered.
|
||||
#if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED <= __MAC_10_6
|
||||
|
||||
#define __AUDACITY_OLD_STD__
|
||||
|
||||
#include <math.h>
|
||||
inline long long int llrint(float __x) { return __builtin_llrintf(__x); }
|
||||
inline long long int llrint(double __x) { return __builtin_llrintl(__x); }
|
||||
inline long long int llrint(long double __x) { return __builtin_llrintl(__x); }
|
||||
|
||||
#include <cmath>
|
||||
using std::isnan;
|
||||
using std::isinf;
|
||||
|
||||
// Need this to define move() and forward()
|
||||
#include <tr1/type_traits>
|
||||
|
||||
// To define make_shared
|
||||
#include <tr1/memory>
|
||||
|
||||
// To define function
|
||||
#include <tr1/functional>
|
||||
|
||||
// To define unordered_set
|
||||
#include <tr1/unordered_set>
|
||||
|
||||
// To define unordered_map and hash
|
||||
#include <tr1/unordered_map>
|
||||
|
||||
#include <tr1/tuple>
|
||||
|
||||
namespace std {
|
||||
using std::tr1::unordered_set;
|
||||
using std::tr1::hash;
|
||||
using std::tr1::unordered_map;
|
||||
using std::tr1::function;
|
||||
using std::tr1::shared_ptr;
|
||||
using std::tr1::weak_ptr;
|
||||
using std::tr1::static_pointer_cast;
|
||||
using std::tr1::remove_reference;
|
||||
using std::tr1::is_unsigned;
|
||||
using std::tr1::is_const;
|
||||
using std::tr1::add_const;
|
||||
using std::tr1::add_pointer;
|
||||
using std::tr1::remove_pointer;
|
||||
using std::tr1::tuple;
|
||||
using std::tr1::get;
|
||||
|
||||
template<typename T> struct add_rvalue_reference {
|
||||
using type = T&&;
|
||||
};
|
||||
|
||||
template<typename X> struct default_delete
|
||||
{
|
||||
default_delete() {}
|
||||
|
||||
// Allow copy from other deleter classes
|
||||
template<typename Y>
|
||||
default_delete(const default_delete<Y>& that)
|
||||
{
|
||||
// Break compilation if Y* does not convert to X*
|
||||
// I should figure out the right use of enable_if instead
|
||||
// Note: YPtr avoids bogus compiler warning for C99 compound literals
|
||||
using YPtr = Y*;
|
||||
static_assert((static_cast<X*>(YPtr{}), true),
|
||||
"Pointer types not convertible");
|
||||
}
|
||||
|
||||
inline void operator() (void *p) const
|
||||
{
|
||||
delete static_cast<X*>(p);
|
||||
}
|
||||
};
|
||||
|
||||
// Specialization for arrays
|
||||
template<typename X> struct default_delete<X[]>
|
||||
{
|
||||
// Do not allow copy from other deleter classes
|
||||
inline void operator() (void *p) const
|
||||
{
|
||||
delete[] static_cast<X*>(p);
|
||||
}
|
||||
};
|
||||
|
||||
struct nullptr_t
|
||||
{
|
||||
void* __lx;
|
||||
|
||||
struct __nat {int __for_bool_;};
|
||||
|
||||
nullptr_t() : __lx(0) {}
|
||||
nullptr_t(int __nat::*) : __lx(0) {}
|
||||
|
||||
operator int __nat::*() const {return 0;}
|
||||
|
||||
template <class _Tp>
|
||||
operator _Tp* () const {return 0;}
|
||||
|
||||
template <class _Tp, class _Up>
|
||||
operator _Tp _Up::* () const {return 0;}
|
||||
|
||||
friend bool operator==(nullptr_t, nullptr_t) {return true;}
|
||||
friend bool operator!=(nullptr_t, nullptr_t) {return false;}
|
||||
friend bool operator<(nullptr_t, nullptr_t) {return false;}
|
||||
friend bool operator<=(nullptr_t, nullptr_t) {return true;}
|
||||
friend bool operator>(nullptr_t, nullptr_t) {return false;}
|
||||
friend bool operator>=(nullptr_t, nullptr_t) {return true;}
|
||||
};
|
||||
|
||||
inline nullptr_t __get_nullptr_t() {return nullptr_t(0);}
|
||||
|
||||
#define nullptr std::__get_nullptr_t()
|
||||
|
||||
// "Cast" anything as an rvalue reference.
|
||||
template<typename T> inline typename remove_reference<T>::type&& move(T&& t)
|
||||
{ return static_cast<typename std::remove_reference<T>::type&&>(t); }
|
||||
|
||||
template<typename T, typename D = default_delete<T>> class unique_ptr
|
||||
: private D // use empty base optimization
|
||||
{
|
||||
public:
|
||||
// Default constructor
|
||||
unique_ptr() {}
|
||||
|
||||
// Implicit constrution from nullptr
|
||||
unique_ptr(nullptr_t) {}
|
||||
|
||||
// Explicit constructor from pointer and optional deleter
|
||||
explicit unique_ptr(T *p_)
|
||||
: p{ p_ } {}
|
||||
explicit unique_ptr(T *p_, const D &d)
|
||||
: D(d), p{ p_ } {}
|
||||
// Template constructors for upcasting
|
||||
template<typename U>
|
||||
explicit unique_ptr(U* p_)
|
||||
: p{ p_ } {}
|
||||
template<typename U>
|
||||
explicit unique_ptr(U* p_, const D& d)
|
||||
: D(d), p{ p_ } {}
|
||||
|
||||
// Copy is disallowed
|
||||
unique_ptr(const unique_ptr &) PROHIBITED;
|
||||
unique_ptr& operator= (const unique_ptr &) PROHIBITED;
|
||||
|
||||
// But move is allowed!
|
||||
unique_ptr(unique_ptr &&that)
|
||||
: D(move(that.get_deleter())), p{ that.release() } { }
|
||||
unique_ptr& operator= (unique_ptr &&that)
|
||||
{
|
||||
if (this != &that) {
|
||||
get_deleter()(p);
|
||||
((D&)*this) = move(that.get_deleter());
|
||||
p = that.release();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign null
|
||||
unique_ptr& operator= (nullptr_t)
|
||||
{
|
||||
get_deleter()(p);
|
||||
p = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Template versions of move for upcasting
|
||||
template<typename U, typename E>
|
||||
unique_ptr(unique_ptr<U, E> &&that)
|
||||
: D(move(that.get_deleter())), p{ that.release() } { }
|
||||
template<typename U, typename E>
|
||||
unique_ptr& operator= (unique_ptr<U, E> &&that)
|
||||
{
|
||||
// Skip the self-assignment test -- self-assignment should go to the non-template overload
|
||||
get_deleter()(p);
|
||||
p = that.release();
|
||||
get_deleter() = move(that.get_deleter());
|
||||
return *this;
|
||||
}
|
||||
|
||||
D& get_deleter() { return *this; }
|
||||
const D& get_deleter() const { return *this; }
|
||||
|
||||
~unique_ptr() { get_deleter()(p); }
|
||||
|
||||
T* operator -> () const { return p; }
|
||||
T& operator * () const { return *p; }
|
||||
T* get() const { return p; }
|
||||
|
||||
// So you can say if(p)
|
||||
explicit operator bool() const { return p != nullptr; }
|
||||
|
||||
// Give up ownership, don't destroy
|
||||
T* release() { T* result = p; p = nullptr; return result; }
|
||||
|
||||
void reset(T* __p = nullptr)
|
||||
{
|
||||
T* old__p = p;
|
||||
p = __p;
|
||||
if (old__p != nullptr)
|
||||
{
|
||||
get_deleter()(old__p);
|
||||
}
|
||||
}
|
||||
|
||||
void swap(unique_ptr& that)
|
||||
{
|
||||
std::swap(p, that.p);
|
||||
std::swap(get_deleter(), that.get_deleter());
|
||||
}
|
||||
|
||||
private:
|
||||
T *p{};
|
||||
};
|
||||
|
||||
// Now specialize the class for array types
|
||||
template<typename T, typename D> class unique_ptr<T[], D>
|
||||
: private D // use empty base optimization
|
||||
{
|
||||
public:
|
||||
// Default constructor
|
||||
unique_ptr() {}
|
||||
|
||||
// Implicit constrution from nullptr
|
||||
unique_ptr(nullptr_t) {}
|
||||
|
||||
// Explicit constructor from pointer
|
||||
explicit unique_ptr(T *p_)
|
||||
: p{ p_ } {}
|
||||
explicit unique_ptr(T *p_, const D &d)
|
||||
: D( d ), p{ p_ } {}
|
||||
// NO template constructor for upcasting!
|
||||
|
||||
// Copy is disallowed
|
||||
unique_ptr(const unique_ptr &) PROHIBITED;
|
||||
unique_ptr& operator= (const unique_ptr &)PROHIBITED;
|
||||
|
||||
// But move is allowed!
|
||||
unique_ptr(unique_ptr &&that)
|
||||
: D( move(that.get_deleter()) ), p{ that.release() } { }
|
||||
unique_ptr& operator= (unique_ptr &&that)
|
||||
{
|
||||
if (this != &that) {
|
||||
get_deleter()(p);
|
||||
p = that.release();
|
||||
((D&)*this) = move(that.get_deleter());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Assign null
|
||||
unique_ptr& operator= (nullptr_t)
|
||||
{
|
||||
get_deleter()(p);
|
||||
p = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
D& get_deleter() { return *this; }
|
||||
const D& get_deleter() const { return *this; }
|
||||
|
||||
// NO template versions of move for upcasting!
|
||||
|
||||
~unique_ptr() { get_deleter()(p); }
|
||||
|
||||
// No operator ->, but [] instead
|
||||
T& operator [] (size_t n) const { return p[n]; }
|
||||
|
||||
T& operator * () const { return *p; }
|
||||
T* get() const { return p; }
|
||||
|
||||
// So you can say if(p)
|
||||
explicit operator bool() const { return p != nullptr; }
|
||||
|
||||
// Give up ownership, don't destroy
|
||||
T* release() { T* result = p; p = nullptr; return result; }
|
||||
|
||||
void reset(T* __p = nullptr)
|
||||
{
|
||||
T* old__p = p;
|
||||
p = __p;
|
||||
if (old__p != nullptr)
|
||||
{
|
||||
get_deleter()(old__p);
|
||||
}
|
||||
}
|
||||
|
||||
void swap(unique_ptr& that)
|
||||
{
|
||||
std::swap(p, that.p);
|
||||
std::swap(get_deleter(), that.get_deleter());
|
||||
}
|
||||
|
||||
private:
|
||||
T *p{};
|
||||
};
|
||||
|
||||
// Equality operators for unique_ptr, don't need the specializations for array case
|
||||
template<typename U, typename E>
|
||||
inline bool operator== (nullptr_t, const unique_ptr<U, E>& ptr)
|
||||
{
|
||||
return ptr.get() == nullptr;
|
||||
}
|
||||
template<typename U, typename E>
|
||||
inline bool operator== (const unique_ptr<U, E>& ptr, nullptr_t)
|
||||
{
|
||||
return ptr.get() == nullptr;
|
||||
}
|
||||
template<typename U, typename E, typename V, typename F>
|
||||
inline bool operator == (const unique_ptr<U, E> &ptr1,
|
||||
const unique_ptr<V, F> &ptr2)
|
||||
{
|
||||
return ptr1.get() == ptr2.get();
|
||||
}
|
||||
|
||||
template<typename U, typename E> inline bool operator != (nullptr_t, const unique_ptr<U, E> &ptr) { return !(ptr == nullptr); }
|
||||
template<typename U, typename E> inline bool operator != (const unique_ptr<U, E> &ptr, nullptr_t) { return !(ptr == nullptr); }
|
||||
template<typename U, typename E, typename V, typename F> inline bool operator != (const unique_ptr<U, E>& ptr1, const unique_ptr<V, F> &ptr2)
|
||||
{ return !(ptr1 == ptr2); }
|
||||
|
||||
// Forward -- pass along rvalue references as rvalue references, anything else as it is
|
||||
// (Because the appropriate overload is taken, and "reference collapse" applies to the return type)
|
||||
template<typename T> inline T&& forward(typename remove_reference<T>::type& t)
|
||||
{ return static_cast<T&&>(t); }
|
||||
template<typename T> inline T&& forward(typename remove_reference<T>::type&& t)
|
||||
{ return static_cast<T&&>(t); }
|
||||
|
||||
// Declared but never defined, and typically used in decltype constructs
|
||||
template<typename T>
|
||||
typename std::add_rvalue_reference<T>::type declval() //noexcept
|
||||
;
|
||||
|
||||
// We need make_shared for ourselves, because the library doesn't use variadics
|
||||
template<typename X, typename... Args> inline shared_ptr<X> make_shared(Args&&... args)
|
||||
{
|
||||
return shared_ptr<X>{ safenew X(forward<Args>(args)...) };
|
||||
}
|
||||
// From LLVM c++11 and modified
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
template<class _Ep>
|
||||
class initializer_list
|
||||
{
|
||||
const _Ep* __begin_;
|
||||
size_t __size_;
|
||||
|
||||
initializer_list(const _Ep* __b, size_t __s)
|
||||
: __begin_(__b),
|
||||
__size_(__s)
|
||||
{}
|
||||
public:
|
||||
typedef _Ep value_type;
|
||||
typedef const _Ep& reference;
|
||||
typedef const _Ep& const_reference;
|
||||
typedef size_t size_type;
|
||||
|
||||
typedef const _Ep* iterator;
|
||||
typedef const _Ep* const_iterator;
|
||||
|
||||
initializer_list() : __begin_(nullptr), __size_(0) {}
|
||||
|
||||
size_t size() const {return __size_;}
|
||||
|
||||
const _Ep* begin() const {return __begin_;}
|
||||
|
||||
const _Ep* end() const {return __begin_ + __size_;}
|
||||
};
|
||||
|
||||
template<class _Ep>
|
||||
inline
|
||||
const _Ep*
|
||||
begin(initializer_list<_Ep> __il)
|
||||
{
|
||||
return __il.begin();
|
||||
}
|
||||
|
||||
template<class _Ep>
|
||||
inline
|
||||
const _Ep*
|
||||
end(initializer_list<_Ep> __il)
|
||||
{
|
||||
return __il.end();
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// To define function
|
||||
#include <functional>
|
||||
|
||||
#endif
|
||||
|
||||
#if !(_MSC_VER >= 1800 || __cplusplus >= 201402L)
|
||||
/* replicate the very useful C++14 make_unique for those build environments
|
||||
that don't implement it yet.
|
||||
|
Reference in New Issue
Block a user