1#ifndef __AUDACITY_MEMORY_X_H__
2#define __AUDACITY_MEMORY_X_H__
26class ArrayOf :
public std::unique_ptr<X[]>
31 template<
typename Integral>
32 explicit ArrayOf(Integral count,
bool initialize =
false)
34 static_assert(std::is_unsigned<Integral>::value,
"Unsigned arguments only");
41 :
std::unique_ptr < X[] >
42 (
std::move((
std::unique_ptr < X[] >&)(that)))
47 std::unique_ptr<X[]>::operator=(std::move(that));
52 std::unique_ptr<X[]>::operator=(std::move(that));
56 template<
typename Integral >
58 bool initialize =
false)
60 static_assert(std::is_unsigned<Integral>::value,
"Unsigned arguments only");
63 std::unique_ptr<X[]>::reset(
safenew X[count]{});
66 std::unique_ptr<X[]>::reset(
safenew X[count]);
85 template<
typename Integral>
90 template<
typename Integral1,
typename Integral2 >
91 ArraysOf(Integral1 N, Integral2 M,
bool initialize =
false)
94 static_assert(std::is_unsigned<Integral1>::value,
"Unsigned arguments only");
95 static_assert(std::is_unsigned<Integral2>::value,
"Unsigned arguments only");
96 for (
size_t ii = 0; ii < N; ++ii)
108 template<
typename Integral >
114 template<
typename Integral >
115 void reinit(Integral count,
bool initialize)
120 template<
typename Integral1,
typename Integral2 >
121 void reinit(Integral1 countN, Integral2 countM,
bool initialize =
false)
123 static_assert(std::is_unsigned<Integral1>::value,
"Unsigned arguments only");
124 static_assert(std::is_unsigned<Integral2>::value,
"Unsigned arguments only");
126 for (
size_t ii = 0; ii < countN; ++ii)
127 (*
this)[ii].reinit(countM, initialize);
139template<
typename T >
145template <
typename Character =
char>
200template<
typename T >
210template<
typename T >
213 using std::unique_ptr< T, RestoreValue<T> >::reset;
227 std::unique_ptr < T, RestoreValue<T> >::operator=(std::move(that));
233template<
typename T >
237template<
typename T >
245template<
typename Value,
typename Category = std::forward_iterator_tag >
259template <
typename Iterator>
265 :
std::pair<Iterator, Iterator> ( a, b ) {}
268 :
std::pair<Iterator, Iterator> (
std::move(a),
std::move(b) ) {}
273 Iterator
begin()
const {
return this->first; }
274 Iterator
end()
const {
return this->second; }
280 explicit operator bool ()
const {
return !this->
empty(); }
281 size_t size()
const {
return std::distance(this->
begin(), this->
end()); }
284 {
return std::find(this->
begin(), this->
end(), t); }
286 template <
typename T>
long index(
const T &t)
const
288 auto iter = this->
find(t);
289 if (iter == this->
end())
291 return std::distance(this->
begin(), iter);
294 template <
typename T>
bool contains(
const T &t)
const
295 {
return this->
end() != this->
find(t); }
298 {
return std::find_if(this->
begin(), this->
end(), f); }
300 template <
typename F>
long index_if(
const F &f)
const
303 if (iter == this->
end())
305 return std::distance(this->
begin(), iter);
309 template <
typename F>
bool all_of(
const F &f)
const
312 [&](
typename std::iterator_traits<Iterator>::reference v)
314 return !this->
any_of( notF );
317 template <
typename F>
bool any_of(
const F &f)
const
320 template <
typename F>
bool none_of(
const F &f)
const
321 {
return !this->
any_of(f); }
324 {
const T&&
operator () (T &&v)
const {
return std::forward(v); } };
330 typename Binary = std::plus< R >,
335 Binary binary_op = {},
340 for (
auto&& v : *
this)
341 result = binary_op(result, unary_op(v));
349 typename Binary = std::plus< R >,
350 typename R2,
typename C
355 R2 (C :: * pmf) ()
const
358 return this->
accumulate( init, binary_op, std::mem_fn( pmf ) );
363 typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
364 typename R =
decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
366 R
min( Unary unary_op = {} )
const
369 std::numeric_limits< R >::max(),
370 (
const R&(*)(
const R&,
const R&))
std::min,
376 typename R2,
typename C,
379 R
min( R2 (C :: * pmf) ()
const )
const
381 return this->
min( std::mem_fn( pmf ) );
385 typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
386 typename R =
decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
388 R
max( Unary unary_op = {} )
const
391 std::numeric_limits< R >::lowest(),
392 (
const R&(*)(
const R&,
const R&)) std::max,
398 typename R2,
typename C,
401 R
max( R2 (C :: * pmf) ()
const )
const
403 return this->
max( std::mem_fn( pmf ) );
407 typename Unary = identity< decltype( *std::declval<Iterator>() ) >,
408 typename R =
decltype( std::declval<Unary>()( *std::declval<Iterator>() ) )
410 R
sum( Unary unary_op = {} )
const
420 typename R2,
typename C,
423 R
sum( R2 (C :: * pmf) ()
const )
const
425 return this->
sum( std::mem_fn( pmf ) );
429template<
typename Iterator>
436template<
typename Container >
440 return { container.begin(), container.end() };
443template<
typename Container >
447 return { container.begin(), container.end() };
451template<
typename Container,
typename Iterator,
typename Function >
455 std::transform( first, last, std::back_inserter( result ),
fn );
459template<
typename OutContainer,
typename InContainer,
typename Function >
462 return transform_range<OutContainer>(
463 inContainer.begin(), inContainer.end(),
fn );
473 std::hardware_destructive_interference_size
481 static void *
operator new(std::size_t count, std::align_val_t al);
482 static void operator delete(
void *ptr, std::align_val_t al);
484#if defined (_MSC_VER) && defined(_DEBUG)
488 static void *
operator new(
489 std::size_t count, std::align_val_t al, int,
const char *, int)
490 {
return operator new(count, al); }
491 static void operator delete(
492 void *ptr, std::align_val_t al, int,
const char *, int)
493 {
return operator delete(ptr, al); }
504 template<
typename... Args>
514 <T>(std::forward<Args>(args)...);
530 T::operator =(other);
536 T::operator =(std::move(other));
541#define QUANTIZED_TIME(time, rate) (floor(((double)(time) * (rate)) + 0.5) / (rate))
543#define DB_TO_LINEAR(x) (pow(10.0, (x) / 20.0))
544#define LINEAR_TO_DB(x) (20.0 * log10(x))
546#define MAX_AUDIO (1. - 1./(1<<15))
548#include <type_traits>
553template <
typename Visitor,
typename Variant>
555 using Var = std::remove_reference_t<Variant>;
556 using Alt = std::variant_alternative_t<0, Var>;
557 using QAlt = std::conditional_t<
558 std::is_const_v<Var>,
const Alt,
Alt >;
559 using Arg = std::conditional_t<std::is_lvalue_reference_v<Variant>,
560 std::add_lvalue_reference_t<QAlt>, std::add_rvalue_reference_t<QAlt>
563 using type =
decltype( std::invoke(
564 std::forward<Visitor>( std::declval<Visitor>() ),
565 std::declval<Arg>() ) );
569template <
typename Visitor,
typename Variant>
575 throw std::invalid_argument{
"Bad variant"};
579template <
size_t Index,
size_t... Indices,
typename Visitor,
typename Variant>
584 if (
const auto pValue = std::get_if<Index>(&var)) {
585 if constexpr (std::is_lvalue_reference_v<Variant>)
586 return std::invoke( std::forward<Visitor>(vis), (*pValue) );
588 return std::invoke( std::forward<Visitor>(vis), std::move(*pValue) );
592 std::forward<Visitor>(vis), std::forward<Variant>(var));
596template <
size_t... Indices,
typename Visitor,
typename Variant>
597auto VisitHelper(std::index_sequence<Indices...>, Visitor &&vis, Variant &&var)
601 std::forward<Visitor>(vis), std::forward<Variant>(var) );
610template <
typename Visitor,
typename Variant>
611auto Visit(Visitor &&vis, Variant &&var)
613 constexpr auto size = std::variant_size_v<std::remove_reference_t<Variant>>;
614 return VisitHelper( std::make_index_sequence<size>{},
615 std::forward<Visitor>(vis), std::forward<Variant>(var) );
622 static_assert(AtomicUniquePointer::is_always_lock_free);
623 using std::atomic<T*>::atomic;
629 delete this->exchange(p, std::memory_order_release);
632 template<
typename... Args>
void emplace(Args &&... args) {
638 using std::atomic<T*>::fetch_add;
639 using std::atomic<T*>::fetch_sub;
ValueRestorer< T > valueRestorer(T &var)
inline functions provide convenient parameter type deduction
struct UTILITY_API alignas(64) NonInterferingBase
Non-template helper for class template NonInterfering.
auto Visit(Visitor &&vis, Variant &&var)
Mimic some of std::visit, for the case of one visitor only.
std::unique_ptr< Character[], freer > MallocString
Container transform_range(Iterator first, Iterator last, Function &&fn)
IteratorRange< Iterator > make_iterator_range(const Iterator &i1, const Iterator &i2)
auto VisitHelper(Visitor &&, Variant &&) -> typename VisitHelperReturn< Visitor, Variant >::type
Help to define Visit() below.
std::unique_ptr< T, Destroyer< T > > Destroy_ptr
a convenience for using Destroyer
Finally(F) -> Finally< F >
OutContainer transform_container(InContainer &inContainer, Function &&fn)
std::unique_ptr< T, freer > MallocPtr
This simplifies arrays of arrays, each array separately allocated with NEW[] But it might be better t...
ArrayOf(const ArrayOf &)=delete
ArrayOf & operator=(ArrayOf &&that)
void reinit(Integral count, bool initialize=false)
ArrayOf(Integral count, bool initialize=false)
void reinit(Integral count)
ArraysOf(Integral1 N, Integral2 M, bool initialize=false)
ArraysOf(const ArraysOf &)=delete
ArraysOf & operator=(ArraysOf &&that)
void reinit(Integral1 countN, Integral2 countM, bool initialize=false)
void reinit(Integral count, bool initialize)
Set a variable temporarily in a scope.
ValueRestorer(T &var, const T &newValue)
ValueRestorer & operator=(ValueRestorer &&that)
ValueRestorer(ValueRestorer &&that)
void emplace(Args &&... args)
reset to a pointer to a new object with given ctor arguments
A deleter class to supply the second template parameter of unique_ptr for classes like wxWindow that ...
void operator()(T *p) const
"finally" as in The C++ Programming Language, 4th ed., p. 358 Useful for defining ad-hoc RAII actions...
const T && operator()(T &&v) const
A convenience for use with range-for.
R accumulate(R init, Binary binary_op, R2(C ::*pmf)() const) const
bool contains(const T &t) const
R sum(R2(C ::*pmf)() const) const
R sum(Unary unary_op={}) const
R accumulate(R init, Binary binary_op={}, Unary unary_op={}) const
bool all_of(const F &f) const
std::reverse_iterator< Iterator > reverse_iterator
iterator find_if(const F &f) const
iterator find(const T &t) const
IteratorRange(Iterator &&a, Iterator &&b)
long index(const T &t) const
R max(Unary unary_op={}) const
IteratorRange< reverse_iterator > reversal() const
R min(R2(C ::*pmf)() const) const
bool any_of(const F &f) const
long index_if(const F &f) const
reverse_iterator rend() const
bool none_of(const F &f) const
R min(Unary unary_op={}) const
IteratorRange(const Iterator &a, const Iterator &b)
reverse_iterator rbegin() const
R max(R2(C ::*pmf)() const) const
void Set(T &&other)
Allow assignment from default-aligned base type.
void Set(const T &other)
Allow assignment from default-aligned base type.
Structure used by ValueRestorer.
void operator()(T *p) const
Workaround for std::make_shared not working on macOs with over-alignment.
static std::shared_ptr< T > make_shared(Args &&...args)
A convenience for defining iterators that return rvalue types, so that they cooperate correctly with ...
ptrdiff_t difference_type
Category iterator_category
Help to define Visit() below.
std::conditional_t< std::is_const_v< Var >, const Alt, Alt > QAlt
decltype(std::invoke(std::forward< Visitor >(std::declval< Visitor >()), std::declval< Arg >())) type
std::remove_reference_t< Variant > Var
std::conditional_t< std::is_lvalue_reference_v< Variant >, std::add_lvalue_reference_t< QAlt >, std::add_rvalue_reference_t< QAlt > > Arg
std::variant_alternative_t< 0, Var > Alt
void operator()(void *p) const