Skip to content

Commit

Permalink
adopt C++20 Ranges library
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiapoirier committed Jun 4, 2023
1 parent db274c5 commit 4ccdb6a
Show file tree
Hide file tree
Showing 33 changed files with 222 additions and 217 deletions.
6 changes: 3 additions & 3 deletions bufferoverride/bufferoverrideformalities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ void BufferOverride::initialize()
}
mAudioOutputValues.assign(numChannels, 0.0f);

std::for_each(mDecayFilters.begin(), mDecayFilters.end(), [this, numChannels](auto& filters)
std::ranges::for_each(mDecayFilters, [this, numChannels](auto& filters)
{
filters.assign(numChannels, dfx::IIRFilter(getsamplerate()));
});
Expand Down Expand Up @@ -172,9 +172,9 @@ void BufferOverride::reset()
mDivisorLFO.reset();
mBufferLFO.reset();

std::for_each(mDecayFilters.begin(), mDecayFilters.end(), [](auto& filters)
std::ranges::for_each(mDecayFilters, [](auto& filters)
{
std::for_each(filters.begin(), filters.end(), [](auto& filter)
std::ranges::for_each(filters, [](auto& filter)
{
filter.reset();
filter.setCoefficients(dfx::IIRFilter::kUnityCoeff);
Expand Down
12 changes: 6 additions & 6 deletions bufferoverride/bufferoverrideprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ void BufferOverride::updateBuffer(size_t samplePos, bool& ioViewDataChanged)
//-----------------------CALCULATE BUFFER DECAY-------------------------
mPrevMinibufferDecayGain = mMinibufferDecayGain;
std::swap(mCurrentDecayFilters, mPrevDecayFilters);
std::for_each(mCurrentDecayFilters.begin(), mCurrentDecayFilters.end(), [](auto& filter){ filter.reset(); });
std::ranges::for_each(mCurrentDecayFilters, [](auto& filter){ filter.reset(); });
auto& firstFilter = mCurrentDecayFilters.front();

auto const positionNormalized = static_cast<float>(mWritePos) / static_cast<float>(mCurrentForcedBufferSize);
Expand Down Expand Up @@ -435,7 +435,7 @@ void BufferOverride::processaudio(float const* const* inAudio, float* const* out
}
else
{
std::fill(mAudioOutputValues.begin(), mAudioOutputValues.end(), 0.f);
std::ranges::fill(mAudioOutputValues, 0.f);
}

constexpr auto normalizePosition = [](long length, long countDown, float stepAmount)
Expand All @@ -452,8 +452,8 @@ void BufferOverride::processaudio(float const* const* inAudio, float* const* out
auto const fadeInGain = std::sqrt(normalizedPosition);
#endif
// crossfade in the current input
std::transform(mAudioOutputValues.cbegin(), mAudioOutputValues.cend(), mAudioOutputValues.begin(),
[fadeInGain](auto value){ return value * fadeInGain; });
std::ranges::transform(mAudioOutputValues, mAudioOutputValues.begin(),
[fadeInGain](auto value){ return value * fadeInGain; });
mFadeInSmoothCountDown--;
}
if (mFadeOutSmoothCountDown > 0)
Expand All @@ -476,8 +476,8 @@ void BufferOverride::processaudio(float const* const* inAudio, float* const* out
else
{
// fade-out the of end of the shortened minibuffer
std::transform(mAudioOutputValues.cbegin(), mAudioOutputValues.cend(), mAudioOutputValues.begin(),
[fadeOutGain](auto value){ return value * fadeOutGain; });
std::ranges::transform(mAudioOutputValues, mAudioOutputValues.begin(),
[fadeOutGain](auto value){ return value * fadeOutGain; });
}
mFadeOutSmoothCountDown--;
}
Expand Down
2 changes: 1 addition & 1 deletion bufferoverride/gui/bufferoverrideeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ void BufferOverrideEditor::parameterChanged(dfx::ParameterID inParameterID)
//-----------------------------------------------------------------------------
void BufferOverrideEditor::mouseovercontrolchanged(IDGControl* currentControlUnderMouse)
{
if (std::any_of(mHelpDisplays.cbegin(), mHelpDisplays.cend(), std::bind_front(std::equal_to<>{}, nullptr)))
if (std::ranges::any_of(mHelpDisplays, std::bind_front(std::equal_to<>{}, nullptr)))
{
return;
}
Expand Down
32 changes: 17 additions & 15 deletions dfx-library/dfxmidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ This is our MIDI stuff.
#include <algorithm>
#include <cassert>
#include <cmath>
#include <span>

#include "dfxmath.h"

Expand All @@ -54,9 +55,9 @@ void DfxMidi::reset()
}
for (auto& noteAudio : mNoteAudioTable)
{
std::fill(noteAudio.mLastOutValue.begin(), noteAudio.mLastOutValue.end(), 0.0f);
std::ranges::fill(noteAudio.mLastOutValue, 0.f);
noteAudio.mSmoothSamples = 0;
std::for_each(noteAudio.mTails.begin(), noteAudio.mTails.end(), [](auto& tail){ std::fill(tail.begin(), tail.end(), 0.0f); });
std::ranges::for_each(noteAudio.mTails, [](auto& tail){ std::ranges::fill(tail, 0.f); });
}
mSustainQueue.fill(false);

Expand Down Expand Up @@ -86,7 +87,7 @@ void DfxMidi::setSampleRate(double inSampleRate)
mStolenNoteFadeStep = 1.0f / static_cast<float>(mStolenNoteFadeDur);
for (auto& noteAudio : mNoteAudioTable)
{
std::fill(noteAudio.mTails.begin(), noteAudio.mTails.end(), decltype(noteAudio.mTails)::value_type(mStolenNoteFadeDur, 0.f));
std::ranges::fill(noteAudio.mTails, decltype(noteAudio.mTails)::value_type(mStolenNoteFadeDur, 0.f));
}
}

Expand Down Expand Up @@ -143,11 +144,12 @@ void DfxMidi::preprocessEvents(size_t inNumFrames)

// Sort the events in our queue so that they are in chronological order.
// The host is supposed to send them in order, but just in case...
std::stable_sort(mBlockEvents.begin(), std::next(mBlockEvents.begin(), mNumBlockEvents), [](auto const& a, auto const& b)
std::span const activeBlockEvents(mBlockEvents.begin(), mNumBlockEvents);
std::ranges::stable_sort(activeBlockEvents, [](auto const& a, auto const& b)
{
return a.mOffsetFrames < b.mOffsetFrames;
});
std::for_each(mBlockEvents.begin(), mBlockEvents.end(), [inNumFrames](auto& event)
std::ranges::for_each(activeBlockEvents, [inNumFrames](auto& event)
{
assert(event.mOffsetFrames < inNumFrames);
event.mOffsetFrames = std::min(event.mOffsetFrames, inNumFrames - 1);
Expand Down Expand Up @@ -193,12 +195,12 @@ DfxMidi::MusicNote& DfxMidi::getNoteStateMutable(int inMidiNote)
void DfxMidi::insertNote(int inMidiNote)
{
// first check whether this note is already active (could happen in weird sequencers, like Max for example)
auto const nonMatchPortion = std::stable_partition(mNoteQueue.begin(), mNoteQueue.end(), [inMidiNote](auto const& note)
{
return note == inMidiNote;
});
auto const nonMatchPortion = std::ranges::stable_partition(mNoteQueue, [inMidiNote](auto const& note)
{
return note == inMidiNote;
});
// if the note is not already active, shift every note up a position (normal scenario)
if (nonMatchPortion == mNoteQueue.cbegin())
if (nonMatchPortion.begin() == mNoteQueue.cbegin())
{
std::rotate(mNoteQueue.begin(), std::prev(mNoteQueue.end()), mNoteQueue.end());
// then place the new note into the first position
Expand All @@ -211,11 +213,11 @@ void DfxMidi::insertNote(int inMidiNote)
// this function removes a note from the active notes queue
void DfxMidi::removeNote(int inMidiNote)
{
auto const nonMatchPortion = std::stable_partition(mNoteQueue.begin(), mNoteQueue.end(), [inMidiNote](auto const& note)
{
return note != inMidiNote;
});
std::fill(nonMatchPortion, mNoteQueue.end(), kInvalidValue);
auto const nonMatchPortion = std::ranges::stable_partition(mNoteQueue, [inMidiNote](auto const& note)
{
return note != inMidiNote;
});
std::fill(nonMatchPortion.begin(), mNoteQueue.end(), kInvalidValue);

if (auto const latestNote = getLatestNote())
{
Expand Down
8 changes: 4 additions & 4 deletions dfx-library/dfxmisc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ std::string ToLower(std::string_view inText)
{
auto const toLower = std::bind(std::tolower<std::string::value_type>, std::placeholders::_1, std::locale::classic());
std::string result;
std::transform(inText.cbegin(), inText.cend(), std::back_inserter(result), toLower);
std::ranges::transform(inText, std::back_inserter(result), toLower);
return result;
}

Expand Down Expand Up @@ -153,9 +153,9 @@ bool LaunchURL(std::string const& inURL)
#if _WIN32
// Return value is a fake HINSTANCE that will be >32 (if successful) or some error code
// otherwise. If we care about error handling, should update to ShellExecuteEx.
auto const ret = reinterpret_cast<intptr_t>(ShellExecute(nullptr, "open", inURL.c_str(),
nullptr, nullptr, SW_SHOWNORMAL));
return ret > 32;
auto const status = reinterpret_cast<intptr_t>(ShellExecute(nullptr, "open", inURL.c_str(),
nullptr, nullptr, SW_SHOWNORMAL));
return status > 32;
#endif

return false;
Expand Down
12 changes: 6 additions & 6 deletions dfx-library/dfxparameter.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*------------------------------------------------------------------------
Destroy FX Library is a collection of foundation code
for creating audio processing plug-ins.
Copyright (C) 2002-2022 Sophia Poirier
Copyright (C) 2002-2023 Sophia Poirier
This file is part of the Destroy FX Library (version 1.0).
Expand Down Expand Up @@ -214,16 +214,16 @@ void DfxParam::initNames(std::vector<std::string_view> const& inNames)
};

assert(!inNames.empty());
assert(std::all_of(inNames.cbegin(), inNames.cend(), [](auto const& name){ return !name.empty(); }));
assert(std::ranges::all_of(inNames, [](auto const& name){ return !name.empty(); }));
{
std::vector<size_t> lengths;
std::transform(inNames.cbegin(), inNames.cend(), std::back_inserter(lengths), stringLength);
std::ranges::transform(inNames, std::back_inserter(lengths), stringLength);
assert(std::unordered_set<size_t>(lengths.cbegin(), lengths.cend()).size() == lengths.size());
}

// sort the names by length (ascending)
mShortNames.assign(inNames.cbegin(), inNames.cend());
std::sort(mShortNames.begin(), mShortNames.end(), [stringLength](auto const& a, auto const& b)
std::ranges::sort(mShortNames, [stringLength](auto const& a, auto const& b)
{
return stringLength(a) < stringLength(b);
});
Expand Down Expand Up @@ -707,7 +707,7 @@ std::string DfxParam::getname(size_t inMaxLength) const
}

// we want the nearest length match that is equal to or less than the requested maximum
auto const bestMatch = std::min_element(mShortNames.cbegin(), mShortNames.cend(), [inMaxLength](auto const& a, auto const& b)
auto const bestMatch = std::ranges::min_element(mShortNames, [inMaxLength](auto const& a, auto const& b)
{
auto const reduce = [inMaxLength](auto const& string)
{
Expand All @@ -719,7 +719,7 @@ std::string DfxParam::getname(size_t inMaxLength) const
// but if nothing was short enough to fully qualify, truncate the shortest of what we have
if (bestMatch->length() > inMaxLength)
{
auto const shortest = std::min_element(mShortNames.cbegin(), mShortNames.cend(), [](auto const& a, auto const& b)
auto const shortest = std::ranges::min_element(mShortNames, [](auto const& a, auto const& b)
{
return a.length() < b.length();
});
Expand Down
43 changes: 21 additions & 22 deletions dfx-library/dfxplugin.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/*------------------------------------------------------------------------
Destroy FX Library is a collection of foundation code
for creating audio processing plug-ins.
Copyright (C) 2002-2022 Sophia Poirier
Copyright (C) 2002-2023 Sophia Poirier
This file is part of the Destroy FX Library (version 1.0).
Expand Down Expand Up @@ -69,7 +69,8 @@ namespace
{

static std::atomic<bool> sIdleThreadShouldRun {false};
__attribute__((no_destroy)) static std::unique_ptr<std::thread> sIdleThread; // TODO: C++20 use std::jthread, C++23 [[no_destroy]]
// TODO C++23: [[no_destroy]]
__attribute__((no_destroy)) static std::unique_ptr<std::thread> sIdleThread; // TODO C++20: use std::jthread
__attribute__((no_destroy)) static std::mutex sIdleThreadLock;
__attribute__((no_destroy)) static std::unordered_set<DfxPlugin*> sIdleClients;
__attribute__((no_destroy)) static std::mutex sIdleClientsLock;
Expand Down Expand Up @@ -97,8 +98,7 @@ static void DFX_RegisterIdleClient(DfxPlugin* const inIdleClient)
{
{
std::lock_guard const guard(sIdleClientsLock);
std::for_each(sIdleClients.cbegin(), sIdleClients.cend(),
[](auto&& idleClient){ idleClient->do_idle(); });
std::ranges::for_each(sIdleClients, [](auto&& idleClient){ idleClient->do_idle(); });
}
std::this_thread::sleep_for(kIdleTimerInterval);
}
Expand Down Expand Up @@ -177,8 +177,7 @@ DfxPlugin::DfxPlugin(
}

// reset pending notifications
std::for_each(mParametersChangedInProcessHavePosted.begin(), mParametersChangedInProcessHavePosted.end(),
[](auto& flag){ flag.test_and_set(); });
std::ranges::for_each(mParametersChangedInProcessHavePosted, [](auto& flag){ flag.test_and_set(); });
mPresetChangedInProcessHasPosted.test_and_set();
mLatencyChangeHasPosted.test_and_set();
mTailSizeChangeHasPosted.test_and_set();
Expand Down Expand Up @@ -297,8 +296,8 @@ void DfxPlugin::do_initialize()
if (!mInPlaceAudioProcessingAllowed)
{
mInputOutOfPlaceAudioBuffers.assign(getnuminputs(), std::vector<float>(getmaxframes(), 0.0f));
std::transform(mInputOutOfPlaceAudioBuffers.cbegin(), mInputOutOfPlaceAudioBuffers.cend(),
mInputAudioStreams.begin(), [](auto const& buffer){ return buffer.data(); });
std::ranges::transform(mInputOutOfPlaceAudioBuffers, mInputAudioStreams.begin(),
[](auto const& buffer){ return buffer.data(); });
}
#endif // !TARGET_API_AUDIOUNIT

Expand All @@ -308,7 +307,7 @@ void DfxPlugin::do_initialize()

#if TARGET_PLUGIN_USES_DSPCORE
// flag parameter changes to be picked up for DSP cores, which are all instantiated anew during plugin initialize
std::for_each(mParameters.begin(), mParameters.end(), [](auto& parameter){ parameter.setchanged(true); });
std::ranges::for_each(mParameters, [](auto& parameter){ parameter.setchanged(true); });

if (asymmetricalchannels())
{
Expand Down Expand Up @@ -339,8 +338,7 @@ void DfxPlugin::do_initialize()
}
#endif // TARGET_PLUGIN_USES_DSPCORE

std::for_each(mSmoothedAudioValues.cbegin(), mSmoothedAudioValues.cend(),
[sr = getsamplerate()](auto& value){ value.first.setSampleRate(sr); });
std::ranges::for_each(mSmoothedAudioValues, [sr = getsamplerate()](auto& value){ value.first.setSampleRate(sr); });

do_reset();
}
Expand Down Expand Up @@ -402,7 +400,7 @@ void DfxPlugin::do_reset()
#endif

mIsFirstRenderSinceReset = true;
std::for_each(mSmoothedAudioValues.cbegin(), mSmoothedAudioValues.cend(), [](auto& value){ value.first.snap(); });
std::ranges::for_each(mSmoothedAudioValues, [](auto& value){ value.first.snap(); });

#if TARGET_PLUGIN_USES_MIDI
mMidiState.reset();
Expand Down Expand Up @@ -840,9 +838,9 @@ void DfxPlugin::addparametergroup(std::string const& inName, std::vector<dfx::Pa
{
assert(!inName.empty());
assert(!inParameterIndices.empty());
assert(std::none_of(mParameterGroups.cbegin(), mParameterGroups.cend(), [&inName](auto const& item){ return (item.first == inName); }));
assert(std::none_of(inParameterIndices.cbegin(), inParameterIndices.cend(), [this](auto index){ return getparametergroup(index).has_value(); }));
assert(std::all_of(inParameterIndices.cbegin(), inParameterIndices.cend(), std::bind_front(&DfxPlugin::parameterisvalid, this)));
assert(std::ranges::none_of(mParameterGroups, [&inName](auto const& item){ return (item.first == inName); }));
assert(std::ranges::none_of(inParameterIndices, [this](auto index){ return getparametergroup(index).has_value(); }));
assert(std::ranges::all_of(inParameterIndices, std::bind_front(&DfxPlugin::parameterisvalid, this)));
assert(std::unordered_set(inParameterIndices.cbegin(), inParameterIndices.cend()).size() == inParameterIndices.size());

mParameterGroups.emplace_back(inName, std::set(inParameterIndices.cbegin(), inParameterIndices.cend()));
Expand All @@ -851,14 +849,14 @@ void DfxPlugin::addparametergroup(std::string const& inName, std::vector<dfx::Pa
//-----------------------------------------------------------------------------
std::optional<size_t> DfxPlugin::getparametergroup(dfx::ParameterID inParameterID) const
{
auto const foundGroup = std::find_if(mParameterGroups.cbegin(), mParameterGroups.cend(), [inParameterID](auto const& group)
auto const foundGroup = std::ranges::find_if(mParameterGroups, [inParameterID](auto const& group)
{
auto const& indices = group.second;
return (indices.find(inParameterID) != indices.cend());
return indices.contains(inParameterID);
});
if (foundGroup != mParameterGroups.cend())
{
return static_cast<size_t>(std::distance(mParameterGroups.cbegin(), foundGroup));
return static_cast<size_t>(std::ranges::distance(mParameterGroups.cbegin(), foundGroup));
}
return {};
}
Expand Down Expand Up @@ -1303,7 +1301,7 @@ void DfxPlugin::unregisterAllSmoothedAudioValues(DfxPluginCore& owner)
//-----------------------------------------------------------------------------
void DfxPlugin::incrementSmoothedAudioValues(DfxPluginCore* owner)
{
std::for_each(mSmoothedAudioValues.cbegin(), mSmoothedAudioValues.cend(), [owner](auto& value)
std::ranges::for_each(mSmoothedAudioValues, [owner](auto& value)
{
// TODO: is the !owner test vestigial? and now confusing, per the comment in the header declaration?
// (very careful testing required if changed because incorrect managed smoothing stuff has insidious consequences)
Expand All @@ -1326,7 +1324,7 @@ std::optional<double> DfxPlugin::getSmoothedAudioValueTime() const
void DfxPlugin::setSmoothedAudioValueTime(double inSmoothingTimeInSeconds)
{
// TODO: thread safety
std::for_each(mSmoothedAudioValues.cbegin(), mSmoothedAudioValues.cend(), [inSmoothingTimeInSeconds](auto& value)
std::ranges::for_each(mSmoothedAudioValues, [inSmoothingTimeInSeconds](auto& value)
{
value.first.setSmoothingTime(inSmoothingTimeInSeconds);
});
Expand Down Expand Up @@ -1475,7 +1473,8 @@ void DfxPlugin::addchannelconfig(short inNumInputs, short inNumOutputs)
//-----------------------------------------------------------------------------
void DfxPlugin::addchannelconfig(ChannelConfig inChannelConfig)
{
assert(std::find(mChannelConfigs.cbegin(), mChannelConfigs.cend(), inChannelConfig) == mChannelConfigs.cend());
// TODO C++23: std::ranges::contains
assert(std::ranges::find(mChannelConfigs, inChannelConfig) == mChannelConfigs.cend());
assert((inChannelConfig == kChannelConfig_AnyInAnyOut) || ((inChannelConfig.inChannels >= kChannelConfigCount_Any) && (inChannelConfig.outChannels >= kChannelConfigCount_Any)));
#if TARGET_PLUGIN_USES_DSPCORE
assert((inChannelConfig.inChannels == inChannelConfig.outChannels) || (inChannelConfig.inChannels == 1));
Expand Down Expand Up @@ -1994,7 +1993,7 @@ void DfxPlugin::do_processparameters()

if (std::exchange(mIsFirstRenderSinceReset, false))
{
std::for_each(mSmoothedAudioValues.cbegin(), mSmoothedAudioValues.cend(), [](auto& value){ value.first.snap(); });
std::ranges::for_each(mSmoothedAudioValues, [](auto& value){ value.first.snap(); });
}
}

Expand Down
3 changes: 2 additions & 1 deletion dfx-library/dfxsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ DfxSettings::DfxSettings(uint32_t inMagic, DfxPlugin& inPlugin, size_t inSizeofE
mParameterAssignments(mNumParameters)
{
// default to each parameter having its ID equal its index
// TODO C++23: std::ranges::iota
std::iota(mParameterIDMap.begin(), mParameterIDMap.end(), 0);

// calculate some data sizes that are useful to know
Expand Down Expand Up @@ -1525,7 +1526,7 @@ dfx::MidiEventType DfxSettings::getParameterAssignmentType(dfx::ParameterID inPa
// given a parameter ID, find the tag (index) for that parameter in a table of parameter IDs
dfx::ParameterID DfxSettings::getParameterIndexFromMap(dfx::ParameterID inParameterID, std::span<uint32_t const> inSearchIDs)
{
auto const foundID = std::find(inSearchIDs.begin(), inSearchIDs.end(), inParameterID);
auto const foundID = std::ranges::find(inSearchIDs, inParameterID);
if (foundID != inSearchIDs.end())
{
return static_cast<dfx::ParameterID>(std::distance(inSearchIDs.begin(), foundID));
Expand Down
Loading

0 comments on commit 4ccdb6a

Please sign in to comment.