Make a construct_at method amd use it

master
Chris Robinson 2021-10-08 11:05:36 -07:00
parent 8da4eaff29
commit e3b8f8fe27
15 changed files with 44 additions and 37 deletions

View File

@ -279,7 +279,7 @@ ALeffectslot *AllocEffectSlot(ALCcontext *context)
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
ASSUME(slidx < 64);
ALeffectslot *slot{::new(sublist->EffectSlots + slidx) ALeffectslot{}};
ALeffectslot *slot{al::construct_at(sublist->EffectSlots + slidx)};
aluInitEffectPanning(&slot->mSlot, context);
/* Add 1 to avoid source ID 0. */

View File

@ -400,7 +400,7 @@ ALbuffer *AllocBuffer(ALCdevice *device)
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
ASSUME(slidx < 64);
ALbuffer *buffer{::new (sublist->Buffers + slidx) ALbuffer{}};
ALbuffer *buffer{al::construct_at(sublist->Buffers + slidx)};
/* Add 1 to avoid buffer ID 0. */
buffer->id = ((lidx<<6) | slidx) + 1;

View File

@ -187,7 +187,7 @@ ALeffect *AllocEffect(ALCdevice *device)
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
ASSUME(slidx < 64);
ALeffect *effect{::new (sublist->Effects + slidx) ALeffect{}};
ALeffect *effect{al::construct_at(sublist->Effects + slidx)};
InitEffectParams(effect, AL_EFFECT_NULL);
/* Add 1 to avoid effect ID 0. */

View File

@ -143,7 +143,7 @@ void StopEventThrd(ALCcontext *ctx)
evt_data = ring->getWriteVector().first;
} while(evt_data.len == 0);
}
::new(evt_data.buf) AsyncEvent{EventType_KillThread};
al::construct_at(reinterpret_cast<AsyncEvent*>(evt_data.buf), EventType_KillThread);
ring->writeAdvance(1);
ctx->mEventSem.post();

View File

@ -360,7 +360,7 @@ ALfilter *AllocFilter(ALCdevice *device)
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
ASSUME(slidx < 64);
ALfilter *filter{::new(sublist->Filters + slidx) ALfilter{}};
ALfilter *filter{al::construct_at(sublist->Filters + slidx)};
InitFilterParams(filter, AL_FILTER_NULL);
/* Add 1 to avoid filter ID 0. */

View File

@ -743,7 +743,7 @@ ALsource *AllocSource(ALCcontext *context)
auto slidx = static_cast<ALuint>(al::countr_zero(sublist->FreeMask));
ASSUME(slidx < 64);
ALsource *source{::new(sublist->Sources + slidx) ALsource{}};
ALsource *source{al::construct_at(sublist->Sources + slidx)};
/* Add 1 to avoid source ID 0. */
source->id = ((lidx<<6) | slidx) + 1;

View File

@ -468,7 +468,8 @@ bool CalcEffectSlotParams(EffectSlot *slot, EffectSlot **sorted_slots, ContextBa
auto evt_vec = ring->getWriteVector();
if LIKELY(evt_vec.first.len > 0)
{
AsyncEvent *evt{::new(evt_vec.first.buf) AsyncEvent{EventType_ReleaseEffectState}};
AsyncEvent *evt{al::construct_at(reinterpret_cast<AsyncEvent*>(evt_vec.first.buf),
EventType_ReleaseEffectState)};
evt->u.mEffectState = oldstate;
ring->writeAdvance(1);
}
@ -1556,7 +1557,8 @@ void SendSourceStateEvent(ContextBase *context, uint id, VChangeState state)
auto evt_vec = ring->getWriteVector();
if(evt_vec.first.len < 1) return;
AsyncEvent *evt{::new(evt_vec.first.buf) AsyncEvent{EventType_SourceStateChange}};
AsyncEvent *evt{al::construct_at(reinterpret_cast<AsyncEvent*>(evt_vec.first.buf),
EventType_SourceStateChange)};
evt->u.srcstate.id = id;
switch(state)
{
@ -2038,7 +2040,7 @@ void DeviceBase::handleDisconnect(const char *msg, ...)
auto evt_data = ring->getWriteVector().first;
if(evt_data.len > 0)
{
::new(evt_data.buf) AsyncEvent{evt};
al::construct_at(reinterpret_cast<AsyncEvent*>(evt_data.buf), evt);
ring->writeAdvance(1);
ctx->mEventSem.post();
}

View File

@ -873,8 +873,8 @@ void EventManager::addCallback(uint32_t id, uint32_t, const char *type, uint32_t
/* Initialize the NodeProxy to hold the proxy object, add it to the
* active proxy list, and update the sync point.
*/
auto *node = ::new(pw_proxy_get_user_data(proxy)) NodeProxy{id, proxy};
mProxyList.emplace_back(node);
auto *node = static_cast<NodeProxy*>(pw_proxy_get_user_data(proxy));
mProxyList.emplace_back(al::construct_at(node, id, proxy));
syncInit();
}
else if(std::strcmp(type, PW_TYPE_INTERFACE_Metadata) == 0)
@ -902,8 +902,8 @@ void EventManager::addCallback(uint32_t id, uint32_t, const char *type, uint32_t
return;
}
auto *mdata = ::new(pw_proxy_get_user_data(proxy)) MetadataProxy{id, proxy};
mDefaultMetadata = mdata;
auto *mdata = static_cast<MetadataProxy*>(pw_proxy_get_user_data(proxy));
mDefaultMetadata = al::construct_at(mdata, id, proxy);
syncInit();
}
}

View File

@ -15,7 +15,7 @@ EffectSlotArray *EffectSlot::CreatePtrArray(size_t count) noexcept
* space to store a sorted list during mixing.
*/
void *ptr{al_calloc(alignof(EffectSlotArray), EffectSlotArray::Sizeof(count*2))};
return new(ptr) EffectSlotArray{count};
return al::construct_at(static_cast<EffectSlotArray*>(ptr), count);
}
EffectSlot::~EffectSlot()

View File

@ -104,6 +104,11 @@ bool operator!=(const allocator<T,N>&, const allocator<U,M>&) noexcept { return
template<size_t alignment, typename T>
[[gnu::assume_aligned(alignment)]] inline T* assume_aligned(T *ptr) noexcept { return ptr; }
template<typename T, typename ...Args>
constexpr T* construct_at(T *ptr, Args&&...args) noexcept(noexcept(T{std::forward<Args>(args)...}))
{ return ::new(static_cast<void*>(ptr)) T{std::forward<Args>(args)...}; }
/* At least VS 2015 complains that 'ptr' is unused when the given type's
* destructor is trivial (a no-op). So disable that warning for this call.
*/
@ -250,7 +255,7 @@ struct FlexArray {
static std::unique_ptr<FlexArray> Create(index_type count)
{
void *ptr{al_calloc(alignof(FlexArray), Sizeof(count))};
return std::unique_ptr<FlexArray>{new(ptr) FlexArray{count}};
return std::unique_ptr<FlexArray>{al::construct_at(static_cast<FlexArray*>(ptr), count)};
}
FlexArray(index_type size) : mStore{size} { }

View File

@ -58,9 +58,9 @@ class optional {
storage_t mStore;
template<typename... Args>
void doConstruct(Args&& ...args)
void doConstruct(Args&& ...args) noexcept(noexcept(al::construct_at(std::declval<T*>(), std::forward<Args>(args)...)))
{
::new(std::addressof(mStore.mValue)) T{std::forward<Args>(args)...};
al::construct_at(std::addressof(mStore.mValue), std::forward<Args>(args)...);
mStore.mHasValue = true;
}

View File

@ -368,19 +368,18 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(uint rate, ushort irSize,
const al::span<const HrtfStore::Elevation> elevs, const HrirArray *coeffs,
const ubyte2 *delays, const char *filename)
{
std::unique_ptr<HrtfStore> Hrtf;
const size_t irCount{size_t{elevs.back().azCount} + elevs.back().irOffset};
size_t total{sizeof(HrtfStore)};
total = RoundUp(total, alignof(HrtfStore::Field)); /* Align for field infos */
total += sizeof(HrtfStore::Field)*fields.size();
total += sizeof(std::declval<HrtfStore&>().field[0])*fields.size();
total = RoundUp(total, alignof(HrtfStore::Elevation)); /* Align for elevation infos */
total += sizeof(Hrtf->elev[0])*elevs.size();
total += sizeof(std::declval<HrtfStore&>().elev[0])*elevs.size();
total = RoundUp(total, 16); /* Align for coefficients using SIMD */
total += sizeof(Hrtf->coeffs[0])*irCount;
total += sizeof(Hrtf->delays[0])*irCount;
total += sizeof(std::declval<HrtfStore&>().coeffs[0])*irCount;
total += sizeof(std::declval<HrtfStore&>().delays[0])*irCount;
Hrtf.reset(new (al_calloc(16, total)) HrtfStore{});
void *ptr{al_calloc(16, total)};
std::unique_ptr<HrtfStore> Hrtf{al::construct_at(static_cast<HrtfStore*>(ptr))};
if(!Hrtf)
ERR("Out of memory allocating storage for %s.\n", filename);
else
@ -412,10 +411,10 @@ std::unique_ptr<HrtfStore> CreateHrtfStore(uint rate, ushort irSize,
assert(offset == total);
/* Copy input data to storage. */
std::copy(fields.cbegin(), fields.cend(), field_);
std::copy(elevs.cbegin(), elevs.cend(), elev_);
std::copy_n(coeffs, irCount, coeffs_);
std::copy_n(delays, irCount, delays_);
std::uninitialized_copy(fields.cbegin(), fields.cend(), field_);
std::uninitialized_copy(elevs.cbegin(), elevs.cend(), elev_);
std::uninitialized_copy_n(coeffs, irCount, coeffs_);
std::uninitialized_copy_n(delays, irCount, delays_);
/* Finally, assign the storage pointers. */
Hrtf->field = field_;

View File

@ -334,7 +334,7 @@ std::unique_ptr<Compressor> Compressor::Create(const size_t NumChans, const floa
size += sizeof(*Compressor::mHold);
}
auto Comp = std::unique_ptr<Compressor>{new (al_calloc(16, size)) Compressor{}};
auto Comp = CompressorPtr{al::construct_at(static_cast<Compressor*>(al_calloc(16, size)))};
Comp->mNumChans = NumChans;
Comp->mAuto.Knee = AutoKnee;
Comp->mAuto.Attack = AutoAttack;
@ -361,17 +361,15 @@ std::unique_ptr<Compressor> Compressor::Create(const size_t NumChans, const floa
{
if(hold > 1)
{
Comp->mHold = ::new (static_cast<void*>(Comp.get() + 1)) SlidingHold{};
Comp->mHold = al::construct_at(reinterpret_cast<SlidingHold*>(Comp.get() + 1));
Comp->mHold->mValues[0] = -std::numeric_limits<float>::infinity();
Comp->mHold->mExpiries[0] = hold;
Comp->mHold->mLength = hold;
Comp->mDelay = ::new(static_cast<void*>(Comp->mHold + 1)) FloatBufferLine[NumChans];
Comp->mDelay = reinterpret_cast<FloatBufferLine*>(Comp->mHold + 1);
}
else
{
Comp->mDelay = ::new(static_cast<void*>(Comp.get() + 1)) FloatBufferLine[NumChans];
}
std::fill_n(Comp->mDelay, NumChans, FloatBufferLine{});
Comp->mDelay = reinterpret_cast<FloatBufferLine*>(Comp.get() + 1);
std::uninitialized_fill_n(Comp->mDelay, NumChans, FloatBufferLine{});
}
Comp->mCrestCoeff = std::exp(-1.0f / (0.200f * SampleRate)); // 200ms

View File

@ -100,5 +100,6 @@ struct Compressor {
const float ThresholdDb, const float Ratio, const float KneeDb, const float AttackTime,
const float ReleaseTime);
};
using CompressorPtr = std::unique_ptr<Compressor>;
#endif /* CORE_MASTERING_H */

View File

@ -164,7 +164,8 @@ void SendSourceStoppedEvent(ContextBase *context, uint id)
auto evt_vec = ring->getWriteVector();
if(evt_vec.first.len < 1) return;
AsyncEvent *evt{::new(evt_vec.first.buf) AsyncEvent{EventType_SourceStateChange}};
AsyncEvent *evt{al::construct_at(reinterpret_cast<AsyncEvent*>(evt_vec.first.buf),
EventType_SourceStateChange)};
evt->u.srcstate.id = id;
evt->u.srcstate.state = AsyncEvent::SrcState::Stop;
@ -792,7 +793,8 @@ void Voice::mix(const State vstate, ContextBase *Context, const uint SamplesToDo
auto evt_vec = ring->getWriteVector();
if(evt_vec.first.len > 0)
{
AsyncEvent *evt{::new(evt_vec.first.buf) AsyncEvent{EventType_BufferCompleted}};
AsyncEvent *evt{al::construct_at(reinterpret_cast<AsyncEvent*>(evt_vec.first.buf),
EventType_BufferCompleted)};
evt->u.bufcomp.id = SourceID;
evt->u.bufcomp.count = buffers_done;
ring->writeAdvance(1);