Skip to content

Commit

Permalink
BufferView adding template deduction guides (#456)
Browse files Browse the repository at this point in the history
* BufferView adding template deduction guides

* Apply clang-format

* Checking for no SIMD

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
jatinchowdhury18 and github-actions[bot] authored Sep 21, 2023
1 parent 2f79b51 commit 44b9503
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 0 deletions.
109 changes: 109 additions & 0 deletions modules/dsp/chowdsp_buffers/Buffers/chowdsp_BufferView.h
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,113 @@ class BufferView
static constexpr int maxNumChannels = CHOWDSP_BUFFER_MAX_NUM_CHANNELS;
std::array<SampleType*, (size_t) maxNumChannels> channelPointers {};
};

#ifndef DOXYGEN
namespace detail
{
template <typename BufferType, typename SampleType>
struct is_static_buffer
{
static constexpr bool value = false;
};

template <typename T, int nChannels, int nSamples>
struct is_static_buffer<StaticBuffer<T, nChannels, nSamples>, T>
{
static constexpr bool value = true;
};

template <typename BufferType, typename SampleType>
constexpr auto is_static_buffer_v = is_static_buffer<BufferType, SampleType>::value;

static_assert (is_static_buffer_v<StaticBuffer<float, 1, 1>, float> == true);
static_assert (is_static_buffer_v<StaticBuffer<float, 1, 1>, double> != true);
} // namespace detail
#endif // DOXYGEN

/** Template deduction guide for Buffer<float> -> BufferView<float> */
template <typename BufferType,
typename... Ts,
typename = std::enable_if_t<
std::is_same_v<BufferType, Buffer<float>> || detail::is_static_buffer_v<BufferType, float>
#if CHOWDSP_USING_JUCE
|| std::is_same_v<BufferType, juce::AudioBuffer<float>>
#if JUCE_MODULE_AVAILABLE_juce_dsp
|| std::is_same_v<BufferType, juce::dsp::AudioBlock<float>>
#endif
#endif
>>
BufferView (BufferType&, Ts...) -> BufferView<float>;

/** Template deduction guide for const Buffer<float> -> BufferView<const float> */
template <typename BufferType,
typename... Ts,
typename = std::enable_if_t<
std::is_same_v<BufferType, const Buffer<float>> || (std::is_const_v<BufferType> && detail::is_static_buffer_v<std::remove_const_t<BufferType>, float>)
#if CHOWDSP_USING_JUCE
|| std::is_same_v<BufferType, const juce::AudioBuffer<float>>
#if JUCE_MODULE_AVAILABLE_juce_dsp
|| std::is_same_v<std::remove_const_t<BufferType>, juce::dsp::AudioBlock<const float>>
#endif
#endif
>>
BufferView (BufferType&, Ts...) -> BufferView<const float>;

/** Template deduction guide for Buffer<double> -> BufferView<const double> */
template <typename BufferType,
typename... Ts,
typename = std::enable_if_t<
std::is_same_v<BufferType, Buffer<double>> || detail::is_static_buffer_v<BufferType, double>
#if CHOWDSP_USING_JUCE
|| std::is_same_v<BufferType, juce::AudioBuffer<double>>
#if JUCE_MODULE_AVAILABLE_juce_dsp
|| std::is_same_v<BufferType, juce::dsp::AudioBlock<double>>
#endif
#endif
>>
BufferView (BufferType&, Ts...) -> BufferView<double>;

/** Template deduction guide for const Buffer<double> -> BufferView<const double> */
template <typename BufferType,
typename... Ts,
typename = std::enable_if_t<
std::is_same_v<BufferType, const Buffer<double>> || (std::is_const_v<BufferType> && detail::is_static_buffer_v<std::remove_const_t<BufferType>, double>)
#if CHOWDSP_USING_JUCE
|| std::is_same_v<BufferType, const juce::AudioBuffer<double>>
#if JUCE_MODULE_AVAILABLE_juce_dsp
|| std::is_same_v<std::remove_const_t<BufferType>, juce::dsp::AudioBlock<const double>>
#endif
#endif
>>
BufferView (BufferType&, Ts...) -> BufferView<const double>;

#if ! CHOWDSP_NO_XSIMD
/** Template deduction guide for Buffer<xsimd::batch<float>> -> BufferView<const xsimd::batch<float>> */
template <typename BufferType,
typename... Ts,
typename = std::enable_if_t<
std::is_same_v<BufferType, Buffer<xsimd::batch<float>>> || detail::is_static_buffer_v<BufferType, xsimd::batch<float>>>>
BufferView (BufferType&, Ts...) -> BufferView<xsimd::batch<float>>;

/** Template deduction guide for const Buffer<xsimd::batch<float>> -> BufferView<const xsimd::batch<float>> */
template <typename BufferType,
typename... Ts,
typename = std::enable_if_t<
std::is_same_v<BufferType, const Buffer<xsimd::batch<float>>> || (std::is_const_v<BufferType> && detail::is_static_buffer_v<std::remove_const_t<BufferType>, xsimd::batch<float>>)>>
BufferView (BufferType&, Ts...) -> BufferView<const xsimd::batch<float>>;

/** Template deduction guide for Buffer<xsimd::batch<double>> -> BufferView<const xsimd::batch<double>> */
template <typename BufferType,
typename... Ts,
typename = std::enable_if_t<
std::is_same_v<BufferType, Buffer<xsimd::batch<double>>> || detail::is_static_buffer_v<BufferType, xsimd::batch<double>>>>
BufferView (BufferType&, Ts...) -> BufferView<xsimd::batch<double>>;

/** Template deduction guide for const Buffer<xsimd::batch<double>> -> BufferView<const xsimd::batch<double>> */
template <typename BufferType,
typename... Ts,
typename = std::enable_if_t<
std::is_same_v<BufferType, const Buffer<xsimd::batch<double>>> || (std::is_const_v<BufferType> && detail::is_static_buffer_v<std::remove_const_t<BufferType>, xsimd::batch<double>>)>>
BufferView (BufferType&, Ts...) -> BufferView<const xsimd::batch<double>>;
#endif // ! CHOWDSP_NO_XSIMD
} // namespace chowdsp
70 changes: 70 additions & 0 deletions tests/dsp_tests/chowdsp_buffers_test/BufferViewTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,73 @@ TEMPLATE_TEST_CASE ("Buffer View Test", "[dsp][buffers][simd]", float, double, x
}
}
JUCE_END_IGNORE_WARNINGS_GCC_LIKE

TEMPLATE_TEST_CASE ("Buffer View Template Deduction Test", "[dsp][buffers][simd]", float, double, xsimd::batch<float>, xsimd::batch<double>)
{
SECTION ("1D Raw Data")
{
TestType* data = nullptr;
chowdsp::BufferView buffer_view { data, 0 };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view), chowdsp::BufferView<TestType>>);

const TestType* data_const = nullptr;
chowdsp::BufferView buffer_view_const { data_const, 0 };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view_const), chowdsp::BufferView<const TestType>>);
}

SECTION ("2D Raw Data")
{
TestType* const* data = nullptr;
chowdsp::BufferView buffer_view { data, 0, 0 };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view), chowdsp::BufferView<TestType>>);

const TestType* const* data_const = nullptr;
chowdsp::BufferView buffer_view_const { data_const, 0, 0 };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view_const), chowdsp::BufferView<const TestType>>);
}

SECTION ("chowdsp::Buffer")
{
chowdsp::Buffer<TestType> buffer;
chowdsp::BufferView buffer_view { buffer };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view), chowdsp::BufferView<TestType>>);

chowdsp::BufferView buffer_view_const { std::as_const (buffer), 0, -1, 0, -1 };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view_const), chowdsp::BufferView<const TestType>>);
}

SECTION ("chowdsp::StaticBuffer")
{
chowdsp::StaticBuffer<TestType, 1, 1> buffer;
chowdsp::BufferView buffer_view { buffer };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view), chowdsp::BufferView<TestType>>);

const chowdsp::StaticBuffer<TestType, 1, 1> buffer_const;
chowdsp::BufferView buffer_view_const { buffer_const };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view_const), chowdsp::BufferView<const TestType>>);
}

if constexpr (std::is_floating_point_v<TestType>)
{
SECTION ("juce::AudioBuffer")
{
juce::AudioBuffer<TestType> buffer;
chowdsp::BufferView buffer_view { buffer };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view), chowdsp::BufferView<TestType>>);

chowdsp::BufferView buffer_view_const { std::as_const (buffer), 0, -1, 0, -1 };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view_const), chowdsp::BufferView<const TestType>>);
}

SECTION ("juce::dsp::AudioBlock")
{
juce::dsp::AudioBlock<TestType> buffer;
chowdsp::BufferView buffer_view { buffer };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view), chowdsp::BufferView<TestType>>);

juce::dsp::AudioBlock<const TestType> buffer_const;
chowdsp::BufferView buffer_view_const { std::as_const (buffer_const), 0, -1, 0, -1 };
STATIC_REQUIRE (std::is_same_v<decltype (buffer_view_const), chowdsp::BufferView<const TestType>>);
}
}
}

0 comments on commit 44b9503

Please sign in to comment.