mirror of
https://github.com/robbert-vdh/yabridge.git
synced 2026-05-10 12:40:12 +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
|
#pragma once
|
||||||
|
|
||||||
#include <bitsery/traits/core/std_defaults.h>
|
#include <bitsery/traits/core/std_defaults.h>
|
||||||
#include <boost/container/detail/is_contiguous_container.hpp>
|
#include <llvm/small-vector.h>
|
||||||
#include <boost/container/small_vector.hpp>
|
|
||||||
|
|
||||||
namespace bitsery {
|
namespace bitsery {
|
||||||
namespace traits {
|
namespace traits {
|
||||||
|
|
||||||
template <typename T, size_t N, typename Allocator>
|
template <typename T, unsigned N>
|
||||||
struct ContainerTraits<boost::container::small_vector<T, N, Allocator>>
|
struct ContainerTraits<llvm::SmallVector<T, N>>
|
||||||
: public StdContainer<boost::container::small_vector<T, N, Allocator>,
|
: public StdContainer<llvm::SmallVector<T, N>, true, true> {
|
||||||
true,
|
// The small vector implementation needs to be contiguous for this to work
|
||||||
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, size_t N, typename Allocator>
|
template <typename T, unsigned N>
|
||||||
struct BufferAdapterTraits<boost::container::small_vector<T, N, Allocator>>
|
struct BufferAdapterTraits<llvm::SmallVector<T, N>>
|
||||||
: public StdContainerForBufferAdapter<
|
: public StdContainerForBufferAdapter<llvm::SmallVector<T, N>> {};
|
||||||
boost::container::small_vector<T, N, Allocator>> {};
|
|
||||||
|
|
||||||
// And the same extensions again for the type erased version
|
// And the same extensions again for the type erased version
|
||||||
|
|
||||||
template <typename T, typename Allocator>
|
template <typename T>
|
||||||
struct ContainerTraits<boost::container::small_vector_base<T, Allocator>>
|
struct ContainerTraits<llvm::SmallVectorImpl<T>>
|
||||||
: public StdContainer<boost::container::small_vector_base<T, Allocator>,
|
: public StdContainer<llvm::SmallVectorImpl<T>, true, true> {};
|
||||||
true,
|
|
||||||
true> {
|
|
||||||
static_assert(boost::container::dtl::is_contiguous_container<
|
|
||||||
boost::container::small_vector_base<T, Allocator>>::value);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T, typename Allocator>
|
template <typename T>
|
||||||
struct BufferAdapterTraits<boost::container::small_vector_base<T, Allocator>>
|
struct BufferAdapterTraits<llvm::SmallVectorImpl<T>>
|
||||||
: public StdContainerForBufferAdapter<
|
: public StdContainerForBufferAdapter<llvm::SmallVectorImpl<T>> {};
|
||||||
boost::container::small_vector_base<T, Allocator>> {};
|
|
||||||
|
|
||||||
} // namespace traits
|
} // namespace traits
|
||||||
} // namespace bitsery
|
} // namespace bitsery
|
||||||
|
|||||||
@@ -26,11 +26,11 @@
|
|||||||
#ifdef __WINE__
|
#ifdef __WINE__
|
||||||
#include "../wine-host/asio-fix.h"
|
#include "../wine-host/asio-fix.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <llvm/small-vector.h>
|
||||||
#include <asio/io_context.hpp>
|
#include <asio/io_context.hpp>
|
||||||
#include <asio/local/stream_protocol.hpp>
|
#include <asio/local/stream_protocol.hpp>
|
||||||
#include <asio/read.hpp>
|
#include <asio/read.hpp>
|
||||||
#include <asio/write.hpp>
|
#include <asio/write.hpp>
|
||||||
#include <boost/container/small_vector.hpp>
|
|
||||||
#include <ghc/filesystem.hpp>
|
#include <ghc/filesystem.hpp>
|
||||||
|
|
||||||
#include "../bitsery/traits/small-vector.h"
|
#include "../bitsery/traits/small-vector.h"
|
||||||
@@ -71,37 +71,35 @@ using InputAdapter =
|
|||||||
* this way.
|
* this way.
|
||||||
*/
|
*/
|
||||||
template <size_t N>
|
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
|
* The class `SerializationBuffer<N>` is derived from, so we can erase the
|
||||||
* buffer's initial capacity from all functions that work with them.
|
* 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 {
|
namespace asio {
|
||||||
|
|
||||||
template <typename PodType, typename Allocator>
|
// These are copied verbatim `asio::buffer(std::vector<PodType, Allocator>&,
|
||||||
inline ASIO_MUTABLE_BUFFER buffer(
|
// std::size_t)`, since `llvm::SmallVector` is mostly compatible with the STL
|
||||||
boost::container::small_vector_base<PodType, Allocator>& data)
|
// vector.
|
||||||
|
template <typename PodType>
|
||||||
|
inline ASIO_MUTABLE_BUFFER buffer(llvm::SmallVectorImpl<PodType>& data)
|
||||||
ASIO_NOEXCEPT {
|
ASIO_NOEXCEPT {
|
||||||
return ASIO_MUTABLE_BUFFER(
|
return ASIO_MUTABLE_BUFFER(
|
||||||
data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
|
data.size() ? &data[0] : 0, data.size() * sizeof(PodType)
|
||||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
,
|
,
|
||||||
detail::buffer_debug_check<typename boost::container::small_vector_base<
|
detail::buffer_debug_check<
|
||||||
PodType, Allocator>::iterator>(data.begin())
|
typename llvm::SmallVectorImpl<PodType>::iterator>(data.begin())
|
||||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are copied verbatim `asio::buffer(std::vector<PodType,
|
template <typename PodType>
|
||||||
// Allocator>&, std::size_t)`, since `boost::container::small_vector` is
|
inline ASIO_MUTABLE_BUFFER buffer(llvm::SmallVectorImpl<PodType>& data,
|
||||||
// compatible with the STL vector.
|
std::size_t max_size_in_bytes) ASIO_NOEXCEPT {
|
||||||
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 {
|
|
||||||
return ASIO_MUTABLE_BUFFER(
|
return ASIO_MUTABLE_BUFFER(
|
||||||
data.size() ? &data[0] : 0,
|
data.size() ? &data[0] : 0,
|
||||||
data.size() * sizeof(PodType) < max_size_in_bytes
|
data.size() * sizeof(PodType) < max_size_in_bytes
|
||||||
@@ -109,8 +107,8 @@ inline ASIO_MUTABLE_BUFFER buffer(
|
|||||||
: max_size_in_bytes
|
: max_size_in_bytes
|
||||||
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
#if defined(ASIO_ENABLE_BUFFER_DEBUGGING)
|
||||||
,
|
,
|
||||||
detail::buffer_debug_check<typename boost::container::small_vector_base<
|
detail::buffer_debug_check<
|
||||||
PodType, Allocator>::iterator>(data.begin())
|
typename llvm::SmallVectorImpl<PodType>::iterator>(data.begin())
|
||||||
#endif // ASIO_ENABLE_BUFFER_DEBUGGING
|
#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
|
// from the socket, so we can override this for specific function calls
|
||||||
// that potentially need to have their responses handled on the same
|
// that potentially need to have their responses handled on the same
|
||||||
// calling thread (i.e. mutual recursion).
|
// calling thread (i.e. mutual recursion).
|
||||||
const Vst2EventResult response = this->send(
|
const Vst2EventResult response =
|
||||||
[&](asio::local::stream_protocol::socket& socket) {
|
this->send([&](asio::local::stream_protocol::socket& socket) {
|
||||||
return data_converter.send_event(socket, event,
|
return data_converter.send_event(socket, event,
|
||||||
serialization_buffer());
|
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.
|
* thread at all cost we'll just predefine a large buffer for every thread.
|
||||||
*/
|
*/
|
||||||
SerializationBufferBase& serialization_buffer() {
|
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
|
// capacity for a large-ish number of events so we don't have to
|
||||||
// allocate under normal circumstances.
|
// allocate under normal circumstances.
|
||||||
constexpr size_t initial_events_size = sizeof(DynamicVstEvents);
|
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
|
// 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
|
// reallocate the buffer on the next event to free up memory again. This
|
||||||
// won't happen during audio processing.
|
// won't happen during audio processing.
|
||||||
if (buffer.size() > initial_events_size) {
|
if (buffer.size() > initial_events_size * 2) {
|
||||||
buffer.resize(initial_events_size);
|
// NOTE: There's no `.shrink_to_fit()` implementation here, so we'll
|
||||||
buffer.shrink_to_fit();
|
// 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;
|
return buffer;
|
||||||
|
|||||||
@@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <boost/container/string.hpp>
|
|
||||||
|
|
||||||
#include "../serialization/vst3.h"
|
#include "../serialization/vst3.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
|
|||||||
@@ -20,8 +20,8 @@
|
|||||||
|
|
||||||
#include <bitsery/traits/array.h>
|
#include <bitsery/traits/array.h>
|
||||||
#include <bitsery/traits/vector.h>
|
#include <bitsery/traits/vector.h>
|
||||||
|
#include <llvm/small-vector.h>
|
||||||
#include <vestige/aeffectx.h>
|
#include <vestige/aeffectx.h>
|
||||||
#include <boost/container/small_vector.hpp>
|
|
||||||
|
|
||||||
#include "../audio-shm.h"
|
#include "../audio-shm.h"
|
||||||
#include "../bitsery/ext/in-place-optional.h"
|
#include "../bitsery/ext/in-place-optional.h"
|
||||||
@@ -123,18 +123,17 @@ class alignas(16) DynamicVstEvents {
|
|||||||
* the `sysex_data_` field before dumping everything to
|
* the `sysex_data_` field before dumping everything to
|
||||||
* `vst_events_buffer_`.
|
* `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
|
* 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
|
* 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
|
* MiniLab keyboard, REAPER, and D16 Group plugins. We'll store this as an
|
||||||
* associative list of `(index, data)` pairs, where `index` corresponds to
|
* associative list of `(index, data)` pairs, where `index` corresponds to
|
||||||
* an event in `events`. There's no 'small_unordered_map' in
|
* an event in `events`. There's no 'SmallUnorderedMap' equivalent to the
|
||||||
* Boost.Container, so this will have to do.
|
* `SmallVector`.
|
||||||
*/
|
*/
|
||||||
boost::container::small_vector<std::pair<native_size_t, std::string>, 8>
|
llvm::SmallVector<std::pair<native_size_t, std::string>, 8> sysex_data_;
|
||||||
sysex_data_;
|
|
||||||
|
|
||||||
template <typename S>
|
template <typename S>
|
||||||
void serialize(S& 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
|
* MIDI events the host can send at once we have to build this object on the
|
||||||
* heap by hand.
|
* heap by hand.
|
||||||
*/
|
*/
|
||||||
boost::container::small_vector<
|
llvm::SmallVector<
|
||||||
uint8_t,
|
uint8_t,
|
||||||
sizeof(VstEvents) +
|
sizeof(VstEvents) +
|
||||||
((64 - 1) *
|
((64 - 1) *
|
||||||
|
|||||||
@@ -16,18 +16,15 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <llvm/small-vector.h>
|
||||||
#include <pluginterfaces/vst/ivstevents.h>
|
#include <pluginterfaces/vst/ivstevents.h>
|
||||||
#include <boost/container/small_vector.hpp>
|
|
||||||
|
|
||||||
#include "../../bitsery/ext/in-place-variant.h"
|
#include "../../bitsery/ext/in-place-variant.h"
|
||||||
|
#include "../../bitsery/traits/small-vector.h"
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
#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
|
* A wrapper around `DataEvent` for serialization purposes, as this event
|
||||||
@@ -270,7 +267,7 @@ class YaEventList : public Steinberg::Vst::IEventList {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::container::small_vector<YaEvent, 64> events_;
|
llvm::SmallVector<YaEvent, 64> events_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|||||||
@@ -16,20 +16,14 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <llvm/small-vector.h>
|
||||||
#include <pluginterfaces/vst/ivstparameterchanges.h>
|
#include <pluginterfaces/vst/ivstparameterchanges.h>
|
||||||
#include <boost/container/small_vector.hpp>
|
|
||||||
|
|
||||||
#include "../../bitsery/traits/small-vector.h"
|
#include "../../bitsery/traits/small-vector.h"
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wnon-virtual-dtor"
|
#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
|
* 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)`.
|
* This contains pairs of `(sample_offset, value)`.
|
||||||
*/
|
*/
|
||||||
boost::container::small_vector<std::pair<int32, Steinberg::Vst::ParamValue>,
|
llvm::SmallVector<std::pair<int32, Steinberg::Vst::ParamValue>, 16> queue_;
|
||||||
16>
|
|
||||||
queue_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <llvm/small-vector.h>
|
||||||
#include <pluginterfaces/vst/ivstparameterchanges.h>
|
#include <pluginterfaces/vst/ivstparameterchanges.h>
|
||||||
#include <boost/container/small_vector.hpp>
|
|
||||||
|
|
||||||
#include "../../bitsery/traits/small-vector.h"
|
#include "../../bitsery/traits/small-vector.h"
|
||||||
#include "base.h"
|
#include "base.h"
|
||||||
@@ -85,7 +85,7 @@ class YaParameterChanges : public Steinberg::Vst::IParameterChanges {
|
|||||||
/**
|
/**
|
||||||
* The parameter value changes queues.
|
* The parameter value changes queues.
|
||||||
*/
|
*/
|
||||||
boost::container::small_vector<YaParamValueQueue, 16> queues_;
|
llvm::SmallVector<YaParamValueQueue, 16> queues_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|||||||
@@ -112,8 +112,8 @@ class YaProcessData {
|
|||||||
struct Response {
|
struct Response {
|
||||||
// We store raw pointers instead of references so we can default
|
// We store raw pointers instead of references so we can default
|
||||||
// initialize this object during deserialization
|
// initialize this object during deserialization
|
||||||
boost::container::small_vector_base<Steinberg::Vst::AudioBusBuffers>*
|
llvm::SmallVectorImpl<Steinberg::Vst::AudioBusBuffers>* outputs =
|
||||||
outputs = nullptr;
|
nullptr;
|
||||||
std::optional<YaParameterChanges>* output_parameter_changes = nullptr;
|
std::optional<YaParameterChanges>* output_parameter_changes = nullptr;
|
||||||
std::optional<YaEventList>* output_events = 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
|
* be set to point to our shared memory surface that holds the actual audio
|
||||||
* data.
|
* 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
|
* 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
|
* be set to point to our shared memory surface that holds the actual audio
|
||||||
* data.
|
* data.
|
||||||
*/
|
*/
|
||||||
boost::container::small_vector<Steinberg::Vst::AudioBusBuffers, 8> outputs_;
|
llvm::SmallVector<Steinberg::Vst::AudioBusBuffers, 8> outputs_;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Incoming parameter changes.
|
* Incoming parameter changes.
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
//===- llvm/ADT/SmallVector.cpp - 'Normally small' vectors ----------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements the SmallVector class.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
// Taken from
|
||||||
|
// https://github.com/llvm/llvm-project/blob/f14334ffa1191ad734d2a994609cf8220c5b7abf/llvm/lib/Support/SmallVector.cpp
|
||||||
|
|
||||||
|
#include "small-vector.h"
|
||||||
|
|
||||||
|
#define LLVM_ENABLE_EXCEPTIONS
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#ifdef LLVM_ENABLE_EXCEPTIONS
|
||||||
|
#include <stdexcept>
|
||||||
|
#endif
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
// Check that no bytes are wasted and everything is well-aligned.
|
||||||
|
namespace {
|
||||||
|
// These structures may cause binary compat warnings on AIX. Suppress the
|
||||||
|
// warning since we are only using these types for the static assertions below.
|
||||||
|
#if defined(_AIX)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Waix-compat"
|
||||||
|
#endif
|
||||||
|
struct Struct16B {
|
||||||
|
alignas(16) void* X;
|
||||||
|
};
|
||||||
|
struct Struct32B {
|
||||||
|
alignas(32) void* X;
|
||||||
|
};
|
||||||
|
#if defined(_AIX)
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
} // namespace
|
||||||
|
static_assert(sizeof(SmallVector<void*, 0>) ==
|
||||||
|
sizeof(unsigned) * 2 + sizeof(void*),
|
||||||
|
"wasted space in SmallVector size 0");
|
||||||
|
static_assert(alignof(SmallVector<Struct16B, 0>) >= alignof(Struct16B),
|
||||||
|
"wrong alignment for 16-byte aligned T");
|
||||||
|
static_assert(alignof(SmallVector<Struct32B, 0>) >= alignof(Struct32B),
|
||||||
|
"wrong alignment for 32-byte aligned T");
|
||||||
|
static_assert(sizeof(SmallVector<Struct16B, 0>) >= alignof(Struct16B),
|
||||||
|
"missing padding for 16-byte aligned T");
|
||||||
|
static_assert(sizeof(SmallVector<Struct32B, 0>) >= alignof(Struct32B),
|
||||||
|
"missing padding for 32-byte aligned T");
|
||||||
|
static_assert(sizeof(SmallVector<void*, 1>) ==
|
||||||
|
sizeof(unsigned) * 2 + sizeof(void*) * 2,
|
||||||
|
"wasted space in SmallVector size 1");
|
||||||
|
|
||||||
|
static_assert(sizeof(SmallVector<char, 0>) == sizeof(void*) * 2 + sizeof(void*),
|
||||||
|
"1 byte elements have word-sized type for size and capacity");
|
||||||
|
|
||||||
|
/// Report that MinSize doesn't fit into this vector's size type. Throws
|
||||||
|
/// std::length_error or calls report_fatal_error.
|
||||||
|
[[noreturn]] static void report_size_overflow(size_t MinSize, size_t MaxSize);
|
||||||
|
static void report_size_overflow(size_t MinSize, size_t MaxSize) {
|
||||||
|
std::string Reason = "SmallVector unable to grow. Requested capacity (" +
|
||||||
|
std::to_string(MinSize) +
|
||||||
|
") is larger than maximum value for size type (" +
|
||||||
|
std::to_string(MaxSize) + ")";
|
||||||
|
#ifdef LLVM_ENABLE_EXCEPTIONS
|
||||||
|
throw std::length_error(Reason);
|
||||||
|
#else
|
||||||
|
report_fatal_error(Twine(Reason));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Report that this vector is already at maximum capacity. Throws
|
||||||
|
/// std::length_error or calls report_fatal_error.
|
||||||
|
[[noreturn]] static void report_at_maximum_capacity(size_t MaxSize);
|
||||||
|
static void report_at_maximum_capacity(size_t MaxSize) {
|
||||||
|
std::string Reason =
|
||||||
|
"SmallVector capacity unable to grow. Already at maximum size " +
|
||||||
|
std::to_string(MaxSize);
|
||||||
|
#ifdef LLVM_ENABLE_EXCEPTIONS
|
||||||
|
throw std::length_error(Reason);
|
||||||
|
#else
|
||||||
|
report_fatal_error(Twine(Reason));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Moving this function into the header may cause performance regression.
|
||||||
|
template <class Size_T>
|
||||||
|
static size_t getNewCapacity(size_t MinSize,
|
||||||
|
size_t /*TSize*/,
|
||||||
|
size_t OldCapacity) {
|
||||||
|
constexpr size_t MaxSize = std::numeric_limits<Size_T>::max();
|
||||||
|
|
||||||
|
// Ensure we can fit the new capacity.
|
||||||
|
// This is only going to be applicable when the capacity is 32 bit.
|
||||||
|
if (MinSize > MaxSize)
|
||||||
|
report_size_overflow(MinSize, MaxSize);
|
||||||
|
|
||||||
|
// Ensure we can meet the guarantee of space for at least one more element.
|
||||||
|
// The above check alone will not catch the case where grow is called with a
|
||||||
|
// default MinSize of 0, but the current capacity cannot be increased.
|
||||||
|
// This is only going to be applicable when the capacity is 32 bit.
|
||||||
|
if (OldCapacity == MaxSize)
|
||||||
|
report_at_maximum_capacity(MaxSize);
|
||||||
|
|
||||||
|
// In theory 2*capacity can overflow if the capacity is 64 bit, but the
|
||||||
|
// original capacity would never be large enough for this to be a problem.
|
||||||
|
size_t NewCapacity = 2 * OldCapacity + 1; // Always grow.
|
||||||
|
return std::min(std::max(NewCapacity, MinSize), MaxSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Moving this function into the header may cause performance regression.
|
||||||
|
template <class Size_T>
|
||||||
|
void* SmallVectorBase<Size_T>::mallocForGrow(size_t MinSize,
|
||||||
|
size_t TSize,
|
||||||
|
size_t& NewCapacity) {
|
||||||
|
NewCapacity = getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
|
||||||
|
// return llvm::safe_malloc(NewCapacity * TSize);
|
||||||
|
return malloc(NewCapacity * TSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: Moving this function into the header may cause performance regression.
|
||||||
|
template <class Size_T>
|
||||||
|
void SmallVectorBase<Size_T>::grow_pod(void* FirstEl,
|
||||||
|
size_t MinSize,
|
||||||
|
size_t TSize) {
|
||||||
|
size_t NewCapacity =
|
||||||
|
getNewCapacity<Size_T>(MinSize, TSize, this->capacity());
|
||||||
|
void* NewElts;
|
||||||
|
if (BeginX == FirstEl) {
|
||||||
|
NewElts = malloc(NewCapacity * TSize);
|
||||||
|
|
||||||
|
// Copy the elements over. No need to run dtors on PODs.
|
||||||
|
memcpy(NewElts, this->BeginX, size() * TSize);
|
||||||
|
} else {
|
||||||
|
// If this wasn't grown from the inline copy, grow the allocated space.
|
||||||
|
NewElts = realloc(this->BeginX, NewCapacity * TSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
this->BeginX = NewElts;
|
||||||
|
this->Capacity = NewCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
template class llvm::SmallVectorBase<uint32_t>;
|
||||||
|
|
||||||
|
// Disable the uint64_t instantiation for 32-bit builds.
|
||||||
|
// Both uint32_t and uint64_t instantiations are needed for 64-bit builds.
|
||||||
|
// This instantiation will never be used in 32-bit builds, and will cause
|
||||||
|
// warnings when sizeof(Size_T) > sizeof(size_t).
|
||||||
|
#if SIZE_MAX > UINT32_MAX
|
||||||
|
template class llvm::SmallVectorBase<uint64_t>;
|
||||||
|
|
||||||
|
// Assertions to ensure this #if stays in sync with SmallVectorSizeType.
|
||||||
|
static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint64_t),
|
||||||
|
"Expected SmallVectorBase<uint64_t> variant to be in use.");
|
||||||
|
#else
|
||||||
|
static_assert(sizeof(SmallVectorSizeType<char>) == sizeof(uint32_t),
|
||||||
|
"Expected SmallVectorBase<uint32_t> variant to be in use.");
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -196,7 +196,7 @@ class Vst2PluginBridge : PluginBridge<Vst2Sockets<std::jthread>> {
|
|||||||
* we receive so we can send them to host on the audio thread at the end of
|
* we receive so we can send them to host on the audio thread at the end of
|
||||||
* `process_replacing()`.
|
* `process_replacing()`.
|
||||||
*/
|
*/
|
||||||
boost::container::small_vector<DynamicVstEvents, 1> incoming_midi_events_;
|
llvm::SmallVector<DynamicVstEvents, 1> incoming_midi_events_;
|
||||||
/**
|
/**
|
||||||
* Mutex for locking the above event queue, since recieving and processing
|
* Mutex for locking the above event queue, since recieving and processing
|
||||||
* now happens in two different threads.
|
* now happens in two different threads.
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ vst2_plugin_sources = files(
|
|||||||
'../common/plugins.cpp',
|
'../common/plugins.cpp',
|
||||||
'../common/process.cpp',
|
'../common/process.cpp',
|
||||||
'../common/utils.cpp',
|
'../common/utils.cpp',
|
||||||
|
'../include/llvm/small-vector.cpp',
|
||||||
'bridges/vst2.cpp',
|
'bridges/vst2.cpp',
|
||||||
'host-process.cpp',
|
'host-process.cpp',
|
||||||
'utils.cpp',
|
'utils.cpp',
|
||||||
@@ -82,6 +83,7 @@ vst3_plugin_sources = files(
|
|||||||
'../common/plugins.cpp',
|
'../common/plugins.cpp',
|
||||||
'../common/process.cpp',
|
'../common/process.cpp',
|
||||||
'../common/utils.cpp',
|
'../common/utils.cpp',
|
||||||
|
'../include/llvm/small-vector.cpp',
|
||||||
'bridges/vst3.cpp',
|
'bridges/vst3.cpp',
|
||||||
'bridges/vst3-impls/plugin-factory-proxy.cpp',
|
'bridges/vst3-impls/plugin-factory-proxy.cpp',
|
||||||
'bridges/vst3-impls/plug-view-proxy.cpp',
|
'bridges/vst3-impls/plug-view-proxy.cpp',
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ class Vst2Bridge : public HostBridge {
|
|||||||
* practice every host will bundle all events in a single
|
* practice every host will bundle all events in a single
|
||||||
* `effProcessEvents()` call.
|
* `effProcessEvents()` call.
|
||||||
*/
|
*/
|
||||||
boost::container::small_vector<DynamicVstEvents, 1>
|
llvm::SmallVector<DynamicVstEvents, 1>
|
||||||
next_audio_buffer_midi_events_;
|
next_audio_buffer_midi_events_;
|
||||||
/**
|
/**
|
||||||
* Whether `next_audio_buffer_midi_events` should be cleared before
|
* Whether `next_audio_buffer_midi_events` should be cleared before
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <boost/container/small_vector.hpp>
|
#include <llvm/small-vector.h>
|
||||||
|
|
||||||
using namespace std::literals::chrono_literals;
|
using namespace std::literals::chrono_literals;
|
||||||
using namespace std::literals::string_literals;
|
using namespace std::literals::string_literals;
|
||||||
@@ -132,7 +132,7 @@ static const HCURSOR arrow_cursor = LoadCursor(nullptr, IDC_ARROW);
|
|||||||
* @return A non-empty list containing `starting_at` and all of its ancestor
|
* @return A non-empty list containing `starting_at` and all of its ancestor
|
||||||
* windows `starting_at`.
|
* windows `starting_at`.
|
||||||
*/
|
*/
|
||||||
boost::container::small_vector<xcb_window_t, 8> find_ancestor_windows(
|
llvm::SmallVector<xcb_window_t, 8> find_ancestor_windows(
|
||||||
xcb_connection_t& x11_connection,
|
xcb_connection_t& x11_connection,
|
||||||
xcb_window_t starting_at);
|
xcb_window_t starting_at);
|
||||||
|
|
||||||
@@ -1238,7 +1238,7 @@ LRESULT CALLBACK window_proc(HWND handle,
|
|||||||
return DefWindowProc(handle, message, wParam, lParam);
|
return DefWindowProc(handle, message, wParam, lParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::container::small_vector<xcb_window_t, 8> find_ancestor_windows(
|
llvm::SmallVector<xcb_window_t, 8> find_ancestor_windows(
|
||||||
xcb_connection_t& x11_connection,
|
xcb_connection_t& x11_connection,
|
||||||
xcb_window_t starting_at) {
|
xcb_window_t starting_at) {
|
||||||
xcb_window_t current_window = starting_at;
|
xcb_window_t current_window = starting_at;
|
||||||
@@ -1250,8 +1250,7 @@ boost::container::small_vector<xcb_window_t, 8> find_ancestor_windows(
|
|||||||
THROW_X11_ERROR(error);
|
THROW_X11_ERROR(error);
|
||||||
|
|
||||||
const xcb_window_t root = query_reply->root;
|
const xcb_window_t root = query_reply->root;
|
||||||
boost::container::small_vector<xcb_window_t, 8> ancestor_windows{
|
llvm::SmallVector<xcb_window_t, 8> ancestor_windows{current_window};
|
||||||
current_window};
|
|
||||||
while (query_reply->parent != root) {
|
while (query_reply->parent != root) {
|
||||||
current_window = query_reply->parent;
|
current_window = query_reply->parent;
|
||||||
ancestor_windows.push_back(current_window);
|
ancestor_windows.push_back(current_window);
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ host_common_sources = files(
|
|||||||
'../common/plugins.cpp',
|
'../common/plugins.cpp',
|
||||||
'../common/process.cpp',
|
'../common/process.cpp',
|
||||||
'../common/utils.cpp',
|
'../common/utils.cpp',
|
||||||
|
'../include/llvm/small-vector.cpp',
|
||||||
'bridges/common.cpp',
|
'bridges/common.cpp',
|
||||||
'bridges/vst2.cpp',
|
'bridges/vst2.cpp',
|
||||||
'editor.cpp',
|
'editor.cpp',
|
||||||
|
|||||||
@@ -192,9 +192,9 @@ WineXdndProxy::Handle WineXdndProxy::get_handle() {
|
|||||||
return Handle(instance);
|
return Handle(instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WineXdndProxy::begin_xdnd(const boost::container::small_vector_base<
|
void WineXdndProxy::begin_xdnd(
|
||||||
ghc::filesystem::path>& file_paths,
|
const llvm::SmallVectorImpl<ghc::filesystem::path>& file_paths,
|
||||||
HWND tracker_window) {
|
HWND tracker_window) {
|
||||||
if (file_paths.empty()) {
|
if (file_paths.empty()) {
|
||||||
throw std::runtime_error("Cannot drag-and-drop without any files");
|
throw std::runtime_error("Cannot drag-and-drop without any files");
|
||||||
}
|
}
|
||||||
@@ -815,7 +815,7 @@ void CALLBACK dnd_winevent_callback(HWINEVENTHOOK /*hWinEventHook*/,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// This will contain the normal, Unix-style paths to the files
|
// This will contain the normal, Unix-style paths to the files
|
||||||
boost::container::small_vector<fs::path, 4> dragged_files;
|
llvm::SmallVector<fs::path, 4> dragged_files;
|
||||||
for (unsigned int format_idx = 0; format_idx < num_formats; format_idx++) {
|
for (unsigned int format_idx = 0; format_idx < num_formats; format_idx++) {
|
||||||
STGMEDIUM storage{};
|
STGMEDIUM storage{};
|
||||||
if (HRESULT result = tracker_info->dataObject->GetData(
|
if (HRESULT result = tracker_info->dataObject->GetData(
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
#include <xcb/xcb.h>
|
#include <xcb/xcb.h>
|
||||||
#pragma pop_macro("_WIN32")
|
#pragma pop_macro("_WIN32")
|
||||||
|
|
||||||
|
#include <llvm/small-vector.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <boost/container/small_vector.hpp>
|
|
||||||
#include <ghc/filesystem.hpp>
|
#include <ghc/filesystem.hpp>
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
@@ -149,9 +149,9 @@ class WineXdndProxy {
|
|||||||
* Initiate the XDDN protocol by taking ownership of the `XdndSelection`
|
* Initiate the XDDN protocol by taking ownership of the `XdndSelection`
|
||||||
* selection and setting up the event listeners.
|
* selection and setting up the event listeners.
|
||||||
*/
|
*/
|
||||||
void begin_xdnd(const boost::container::small_vector_base<
|
void begin_xdnd(
|
||||||
ghc::filesystem::path>& file_paths,
|
const llvm::SmallVectorImpl<ghc::filesystem::path>& file_paths,
|
||||||
HWND tracker_window);
|
HWND tracker_window);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release ownership of the selection stop listening for X11 events.
|
* Release ownership of the selection stop listening for X11 events.
|
||||||
|
|||||||
Reference in New Issue
Block a user