mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-15 21:15:51 +02:00
Swap Boost.Container's small_vector out for LLVM's
This implementation misses a shrink to fit function, but reassigning the vector with a fresh one should be equivalent.
This commit is contained in:
@@ -17,44 +17,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <bitsery/traits/core/std_defaults.h>
|
||||
#include <boost/container/detail/is_contiguous_container.hpp>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <llvm/small-vector.h>
|
||||
|
||||
namespace bitsery {
|
||||
namespace traits {
|
||||
|
||||
template <typename T, size_t N, typename Allocator>
|
||||
struct ContainerTraits<boost::container::small_vector<T, N, Allocator>>
|
||||
: public StdContainer<boost::container::small_vector<T, N, Allocator>,
|
||||
true,
|
||||
true> {
|
||||
// Unlike `std::vector`, I'm pretty sure
|
||||
// `boost::container::small_vector<bool, N>` is contiguous. So hopefully
|
||||
// this assertion does its thing.
|
||||
static_assert(boost::container::dtl::is_contiguous_container<
|
||||
boost::container::small_vector<T, N, Allocator>>::value);
|
||||
template <typename T, unsigned N>
|
||||
struct ContainerTraits<llvm::SmallVector<T, N>>
|
||||
: public StdContainer<llvm::SmallVector<T, N>, true, true> {
|
||||
// The small vector implementation needs to be contiguous for this to work
|
||||
};
|
||||
|
||||
template <typename T, size_t N, typename Allocator>
|
||||
struct BufferAdapterTraits<boost::container::small_vector<T, N, Allocator>>
|
||||
: public StdContainerForBufferAdapter<
|
||||
boost::container::small_vector<T, N, Allocator>> {};
|
||||
template <typename T, unsigned N>
|
||||
struct BufferAdapterTraits<llvm::SmallVector<T, N>>
|
||||
: public StdContainerForBufferAdapter<llvm::SmallVector<T, N>> {};
|
||||
|
||||
// And the same extensions again for the type erased version
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
struct ContainerTraits<boost::container::small_vector_base<T, Allocator>>
|
||||
: public StdContainer<boost::container::small_vector_base<T, Allocator>,
|
||||
true,
|
||||
true> {
|
||||
static_assert(boost::container::dtl::is_contiguous_container<
|
||||
boost::container::small_vector_base<T, Allocator>>::value);
|
||||
};
|
||||
template <typename T>
|
||||
struct ContainerTraits<llvm::SmallVectorImpl<T>>
|
||||
: public StdContainer<llvm::SmallVectorImpl<T>, true, true> {};
|
||||
|
||||
template <typename T, typename Allocator>
|
||||
struct BufferAdapterTraits<boost::container::small_vector_base<T, Allocator>>
|
||||
: public StdContainerForBufferAdapter<
|
||||
boost::container::small_vector_base<T, Allocator>> {};
|
||||
template <typename T>
|
||||
struct BufferAdapterTraits<llvm::SmallVectorImpl<T>>
|
||||
: public StdContainerForBufferAdapter<llvm::SmallVectorImpl<T>> {};
|
||||
|
||||
} // namespace traits
|
||||
} // namespace bitsery
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
#ifdef __WINE__
|
||||
#include "../wine-host/asio-fix.h"
|
||||
#endif
|
||||
#include <llvm/small-vector.h>
|
||||
#include <asio/io_context.hpp>
|
||||
#include <asio/local/stream_protocol.hpp>
|
||||
#include <asio/read.hpp>
|
||||
#include <asio/write.hpp>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <ghc/filesystem.hpp>
|
||||
|
||||
#include "../bitsery/traits/small-vector.h"
|
||||
@@ -71,37 +71,35 @@ using InputAdapter =
|
||||
* this way.
|
||||
*/
|
||||
template <size_t N>
|
||||
using SerializationBuffer = boost::container::small_vector<uint8_t, N>;
|
||||
using SerializationBuffer = llvm::SmallVector<uint8_t, N>;
|
||||
|
||||
/**
|
||||
* The class `SerializationBuffer<N>` is derived from, so we can erase the
|
||||
* buffer's initial capacity from all functions that work with them.
|
||||
*/
|
||||
using SerializationBufferBase = boost::container::small_vector_base<uint8_t>;
|
||||
using SerializationBufferBase = llvm::SmallVectorImpl<uint8_t>;
|
||||
|
||||
namespace asio {
|
||||
|
||||
template <typename PodType, typename Allocator>
|
||||
inline ASIO_MUTABLE_BUFFER buffer(
|
||||
boost::container::small_vector_base<PodType, Allocator>& data)
|
||||
// These are copied verbatim `asio::buffer(std::vector<PodType, Allocator>&,
|
||||
// std::size_t)`, since `llvm::SmallVector` is mostly compatible with the STL
|
||||
// vector.
|
||||
template <typename PodType>
|
||||
inline ASIO_MUTABLE_BUFFER buffer(llvm::SmallVectorImpl<PodType>& data)
|
||||
ASIO_NOEXCEPT {
|
||||
return ASIO_MUTABLE_BUFFER(
|
||||
data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
,
|
||||
detail::buffer_debug_check<typename boost::container::small_vector_base<
|
||||
PodType, Allocator>::iterator>(data.begin())
|
||||
detail::buffer_debug_check<
|
||||
typename llvm::SmallVectorImpl<PodType>::iterator>(data.begin())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
);
|
||||
}
|
||||
|
||||
// These are copied verbatim `asio::buffer(std::vector<PodType,
|
||||
// Allocator>&, std::size_t)`, since `boost::container::small_vector` is
|
||||
// compatible with the STL vector.
|
||||
template <typename PodType, typename Allocator>
|
||||
inline ASIO_MUTABLE_BUFFER buffer(
|
||||
boost::container::small_vector_base<PodType, Allocator>& data,
|
||||
std::size_t max_size_in_bytes) ASIO_NOEXCEPT {
|
||||
template <typename PodType>
|
||||
inline ASIO_MUTABLE_BUFFER buffer(llvm::SmallVectorImpl<PodType>& data,
|
||||
std::size_t max_size_in_bytes) ASIO_NOEXCEPT {
|
||||
return ASIO_MUTABLE_BUFFER(
|
||||
data.size() ? &data[0] : 0,
|
||||
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||
@@ -109,8 +107,8 @@ inline ASIO_MUTABLE_BUFFER buffer(
|
||||
: max_size_in_bytes
|
||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||
,
|
||||
detail::buffer_debug_check<typename boost::container::small_vector_base<
|
||||
PodType, Allocator>::iterator>(data.begin())
|
||||
detail::buffer_debug_check<
|
||||
typename llvm::SmallVectorImpl<PodType>::iterator>(data.begin())
|
||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||
);
|
||||
}
|
||||
|
||||
@@ -205,8 +205,8 @@ class Vst2EventHandler : public AdHocSocketHandler<Thread> {
|
||||
// from the socket, so we can override this for specific function calls
|
||||
// that potentially need to have their responses handled on the same
|
||||
// calling thread (i.e. mutual recursion).
|
||||
const Vst2EventResult response = this->send(
|
||||
[&](asio::local::stream_protocol::socket& socket) {
|
||||
const Vst2EventResult response =
|
||||
this->send([&](asio::local::stream_protocol::socket& socket) {
|
||||
return data_converter.send_event(socket, event,
|
||||
serialization_buffer());
|
||||
});
|
||||
@@ -294,7 +294,7 @@ class Vst2EventHandler : public AdHocSocketHandler<Thread> {
|
||||
* thread at all cost we'll just predefine a large buffer for every thread.
|
||||
*/
|
||||
SerializationBufferBase& serialization_buffer() {
|
||||
// This object also contains a `boost::container::small_vector` that has
|
||||
// This object also contains a `llvm::SmallVector` that has
|
||||
// capacity for a large-ish number of events so we don't have to
|
||||
// allocate under normal circumstances.
|
||||
constexpr size_t initial_events_size = sizeof(DynamicVstEvents);
|
||||
@@ -304,9 +304,13 @@ class Vst2EventHandler : public AdHocSocketHandler<Thread> {
|
||||
// when sending and receiving preset data. In such cases we do want to
|
||||
// reallocate the buffer on the next event to free up memory again. This
|
||||
// won't happen during audio processing.
|
||||
if (buffer.size() > initial_events_size) {
|
||||
buffer.resize(initial_events_size);
|
||||
buffer.shrink_to_fit();
|
||||
if (buffer.size() > initial_events_size * 2) {
|
||||
// NOTE: There's no `.shrink_to_fit()` implementation here, so we'll
|
||||
// just YOLO it and reinitialize the vector since we don't
|
||||
// need the old data
|
||||
buffer = SerializationBuffer<initial_events_size>{};
|
||||
// buffer.resize(initial_events_size);
|
||||
// buffer.shrink_to_fit();
|
||||
}
|
||||
|
||||
return buffer;
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include <boost/container/string.hpp>
|
||||
|
||||
#include "../serialization/vst3.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
|
||||
#include <bitsery/traits/array.h>
|
||||
#include <bitsery/traits/vector.h>
|
||||
#include <llvm/small-vector.h>
|
||||
#include <vestige/aeffectx.h>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#include "../audio-shm.h"
|
||||
#include "../bitsery/ext/in-place-optional.h"
|
||||
@@ -123,18 +123,17 @@ class alignas(16) DynamicVstEvents {
|
||||
* the `sysex_data_` field before dumping everything to
|
||||
* `vst_events_buffer_`.
|
||||
*/
|
||||
boost::container::small_vector<VstEvent, 64> events_;
|
||||
llvm::SmallVector<VstEvent, 64> events_;
|
||||
|
||||
/**
|
||||
* If the host or a plugin sends SysEx data, then we will store that data
|
||||
* here. I've only seen this happen with the combination of an Arturia
|
||||
* MiniLab keyboard, REAPER, and D16 Group plugins. We'll store this as an
|
||||
* associative list of `(index, data)` pairs, where `index` corresponds to
|
||||
* an event in `events`. There's no 'small_unordered_map' in
|
||||
* Boost.Container, so this will have to do.
|
||||
* an event in `events`. There's no 'SmallUnorderedMap' equivalent to the
|
||||
* `SmallVector`.
|
||||
*/
|
||||
boost::container::small_vector<std::pair<native_size_t, std::string>, 8>
|
||||
sysex_data_;
|
||||
llvm::SmallVector<std::pair<native_size_t, std::string>, 8> sysex_data_;
|
||||
|
||||
template <typename S>
|
||||
void serialize(S& s) {
|
||||
@@ -161,7 +160,7 @@ class alignas(16) DynamicVstEvents {
|
||||
* MIDI events the host can send at once we have to build this object on the
|
||||
* heap by hand.
|
||||
*/
|
||||
boost::container::small_vector<
|
||||
llvm::SmallVector<
|
||||
uint8_t,
|
||||
sizeof(VstEvents) +
|
||||
((64 - 1) *
|
||||
|
||||
@@ -16,18 +16,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <llvm/small-vector.h>
|
||||
#include <pluginterfaces/vst/ivstevents.h>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#include "../../bitsery/ext/in-place-variant.h"
|
||||
#include "../../bitsery/traits/small-vector.h"
|
||||
#include "base.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
// FIXME: When used in a Boost.Containers small vector, GCC somehow complains
|
||||
// that the fields in `YaEvent` may be uninitialized (during the
|
||||
// deserialization). This warning only shows up during a unity build.
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
|
||||
/**
|
||||
* A wrapper around `DataEvent` for serialization purposes, as this event
|
||||
@@ -270,7 +267,7 @@ class YaEventList : public Steinberg::Vst::IEventList {
|
||||
}
|
||||
|
||||
private:
|
||||
boost::container::small_vector<YaEvent, 64> events_;
|
||||
llvm::SmallVector<YaEvent, 64> events_;
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
@@ -16,20 +16,14 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <llvm/small-vector.h>
|
||||
#include <pluginterfaces/vst/ivstparameterchanges.h>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#include "../../bitsery/traits/small-vector.h"
|
||||
#include "base.h"
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
||||
// FIXME: When used in a Boost.Containers small vector, GCC somehow complains
|
||||
// that the fields in this class may be uninitialized (during the
|
||||
// deserialization). This warning only shows up during a unity build.
|
||||
#if defined(__GNUC__) && !defined(__llvm__)
|
||||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Wraps around `IParamValueQueue` for serializing a queue containing changes to
|
||||
@@ -102,9 +96,7 @@ class alignas(16) YaParamValueQueue : public Steinberg::Vst::IParamValueQueue {
|
||||
*
|
||||
* This contains pairs of `(sample_offset, value)`.
|
||||
*/
|
||||
boost::container::small_vector<std::pair<int32, Steinberg::Vst::ParamValue>,
|
||||
16>
|
||||
queue_;
|
||||
llvm::SmallVector<std::pair<int32, Steinberg::Vst::ParamValue>, 16> queue_;
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <llvm/small-vector.h>
|
||||
#include <pluginterfaces/vst/ivstparameterchanges.h>
|
||||
#include <boost/container/small_vector.hpp>
|
||||
|
||||
#include "../../bitsery/traits/small-vector.h"
|
||||
#include "base.h"
|
||||
@@ -85,7 +85,7 @@ class YaParameterChanges : public Steinberg::Vst::IParameterChanges {
|
||||
/**
|
||||
* The parameter value changes queues.
|
||||
*/
|
||||
boost::container::small_vector<YaParamValueQueue, 16> queues_;
|
||||
llvm::SmallVector<YaParamValueQueue, 16> queues_;
|
||||
};
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
@@ -112,8 +112,8 @@ class YaProcessData {
|
||||
struct Response {
|
||||
// We store raw pointers instead of references so we can default
|
||||
// initialize this object during deserialization
|
||||
boost::container::small_vector_base<Steinberg::Vst::AudioBusBuffers>*
|
||||
outputs = nullptr;
|
||||
llvm::SmallVectorImpl<Steinberg::Vst::AudioBusBuffers>* outputs =
|
||||
nullptr;
|
||||
std::optional<YaParameterChanges>* output_parameter_changes = nullptr;
|
||||
std::optional<YaEventList>* output_events = nullptr;
|
||||
|
||||
@@ -206,7 +206,7 @@ class YaProcessData {
|
||||
* be set to point to our shared memory surface that holds the actual audio
|
||||
* data.
|
||||
*/
|
||||
boost::container::small_vector<Steinberg::Vst::AudioBusBuffers, 8> inputs_;
|
||||
llvm::SmallVector<Steinberg::Vst::AudioBusBuffers, 8> inputs_;
|
||||
|
||||
/**
|
||||
* This contains metadata about the output buffers for every bus. During
|
||||
@@ -214,7 +214,7 @@ class YaProcessData {
|
||||
* be set to point to our shared memory surface that holds the actual audio
|
||||
* data.
|
||||
*/
|
||||
boost::container::small_vector<Steinberg::Vst::AudioBusBuffers, 8> outputs_;
|
||||
llvm::SmallVector<Steinberg::Vst::AudioBusBuffers, 8> outputs_;
|
||||
|
||||
/**
|
||||
* Incoming parameter changes.
|
||||
|
||||
Reference in New Issue
Block a user