no constructors or destructors

This commit is contained in:
Andrew Kelley 2015-08-04 11:03:19 -07:00
parent 28f73ba037
commit 29a914ceba
11 changed files with 72 additions and 126 deletions

View file

@ -176,6 +176,7 @@ libsoundio is programmed in a tiny subset of C++11:
* No STL.
* No `new` or `delete`.
* No `class`. All fields in structs are `public`.
* No constructors or destructors.
* No exceptions or run-time type information.
* No references.
* No linking against libstdc++.

View file

@ -465,7 +465,7 @@ static int refresh_devices(SoundIoPrivate *si) {
SoundIo *soundio = &si->pub;
SoundIoAlsa *sia = &si->backend_data.alsa;
SoundIoDevicesInfo *devices_info = create<SoundIoDevicesInfo>();
SoundIoDevicesInfo *devices_info = allocate<SoundIoDevicesInfo>(1);
if (!devices_info)
return SoundIoErrorNoMem;
devices_info->default_output_index = -1;
@ -473,7 +473,7 @@ static int refresh_devices(SoundIoPrivate *si) {
void **hints;
if (snd_device_name_hint(-1, "pcm", &hints) < 0) {
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
@ -531,11 +531,11 @@ static int refresh_devices(SoundIoPrivate *si) {
}
SoundIoDevicePrivate *dev = create<SoundIoDevicePrivate>();
SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
if (!dev) {
free(name);
free(descr);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
snd_device_name_free_hint(hints);
return SoundIoErrorNoMem;
}
@ -551,7 +551,7 @@ static int refresh_devices(SoundIoPrivate *si) {
soundio_device_unref(device);
free(name);
free(descr);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
snd_device_name_free_hint(hints);
return SoundIoErrorNoMem;
}
@ -577,7 +577,7 @@ static int refresh_devices(SoundIoPrivate *si) {
soundio_device_unref(device);
free(name);
free(descr);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
snd_device_name_free_hint(hints);
return SoundIoErrorNoMem;
}
@ -609,14 +609,14 @@ static int refresh_devices(SoundIoPrivate *si) {
if (err == -ENOENT) {
break;
} else {
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorOpeningDevice;
}
}
if ((err = snd_ctl_card_info(handle, card_info)) < 0) {
snd_ctl_close(handle);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorSystemResources;
}
const char *card_name = snd_ctl_card_info_get_name(card_info);
@ -625,7 +625,7 @@ static int refresh_devices(SoundIoPrivate *si) {
for (;;) {
if (snd_ctl_pcm_next_device(handle, &device_index) < 0) {
snd_ctl_close(handle);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorSystemResources;
}
if (device_index < 0)
@ -643,17 +643,17 @@ static int refresh_devices(SoundIoPrivate *si) {
continue;
} else {
snd_ctl_close(handle);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorSystemResources;
}
}
const char *device_name = snd_pcm_info_get_name(pcm_info);
SoundIoDevicePrivate *dev = create<SoundIoDevicePrivate>();
SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
if (!dev) {
snd_ctl_close(handle);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
SoundIoDevice *device = &dev->pub;
@ -666,7 +666,7 @@ static int refresh_devices(SoundIoPrivate *si) {
if (!device->id || !device->name) {
soundio_device_unref(device);
snd_ctl_close(handle);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
@ -685,14 +685,14 @@ static int refresh_devices(SoundIoPrivate *si) {
if (device_list->append(device)) {
soundio_device_unref(device);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
}
}
snd_ctl_close(handle);
if (snd_card_next(&card_index) < 0) {
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorSystemResources;
}
}
@ -888,11 +888,9 @@ static void outstream_destroy_alsa(SoundIoPrivate *si, SoundIoOutStreamPrivate *
if (osa->handle)
snd_pcm_close(osa->handle);
deallocate(osa->poll_fds, osa->poll_fd_count);
deallocate(osa->chmap, osa->chmap_size);
deallocate(osa->sample_buffer, osa->sample_buffer_size);
free(osa->poll_fds);
free(osa->chmap);
free(osa->sample_buffer);
}
static int os_xrun_recovery(SoundIoOutStreamPrivate *os, int err) {
@ -1394,9 +1392,9 @@ static void instream_destroy_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is
if (isa->handle)
snd_pcm_close(isa->handle);
deallocate(isa->poll_fds, isa->poll_fd_count);
deallocate(isa->chmap, isa->chmap_size);
deallocate(isa->sample_buffer, isa->sample_buffer_size);
free(isa->poll_fds);
free(isa->chmap);
free(isa->sample_buffer);
}
static int instream_open_alsa(SoundIoPrivate *si, SoundIoInStreamPrivate *is) {

View file

@ -173,7 +173,7 @@ static int from_cf_string(CFStringRef string_ref, char **out_str, int *out_str_l
return SoundIoErrorNoMem;
if (!CFStringGetCString(string_ref, buf, max_size, kCFStringEncodingUTF8)) {
deallocate(buf, max_size);
free(buf);
return SoundIoErrorEncodingString;
}
@ -408,8 +408,8 @@ struct RefreshDevices {
static void deinit_refresh_devices(RefreshDevices *rd) {
if (!rd->ok)
unsubscribe_device_listeners(rd->si);
destroy(rd->devices_info);
deallocate((char*)rd->devices, rd->devices_size);
soundio_destroy_devices_info(rd->devices_info);
free(rd->devices);
if (rd->string_ref)
CFRelease(rd->string_ref);
free(rd->device_name);
@ -433,7 +433,7 @@ static int refresh_devices(struct SoundIoPrivate *si) {
RefreshDevices rd = {0};
rd.si = si;
if (!(rd.devices_info = create<SoundIoDevicesInfo>())) {
if (!(rd.devices_info = allocate<SoundIoDevicesInfo>(1))) {
deinit_refresh_devices(&rd);
return SoundIoErrorNoMem;
}
@ -586,7 +586,7 @@ static int refresh_devices(struct SoundIoPrivate *si) {
if (channel_count <= 0)
continue;
SoundIoDevicePrivate *dev = create<SoundIoDevicePrivate>();
SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
if (!dev) {
deinit_refresh_devices(&rd);
return SoundIoErrorNoMem;
@ -602,9 +602,9 @@ static int refresh_devices(struct SoundIoPrivate *si) {
rd.device->id = soundio_str_dupe(rd.device_uid, rd.device_uid_len);
rd.device->name = soundio_str_dupe(rd.device_name, rd.device_name_len);
rd.device->layout_count = 1;
rd.device->layouts = create<SoundIoChannelLayout>();
rd.device->layouts = allocate<SoundIoChannelLayout>(1);
rd.device->format_count = 1;
rd.device->formats = create<SoundIoFormat>();
rd.device->formats = allocate<SoundIoFormat>(1);
if (!rd.device->id || !rd.device->name || !rd.device->layouts || !rd.device->formats) {
deinit_refresh_devices(&rd);

View file

@ -386,7 +386,7 @@ int soundio_dummy_init(SoundIoPrivate *si) {
}
assert(!si->safe_devices_info);
si->safe_devices_info = create<SoundIoDevicesInfo>();
si->safe_devices_info = allocate<SoundIoDevicesInfo>(1);
if (!si->safe_devices_info) {
destroy_dummy(si);
return SoundIoErrorNoMem;
@ -397,7 +397,7 @@ int soundio_dummy_init(SoundIoPrivate *si) {
// create output device
{
SoundIoDevicePrivate *dev = create<SoundIoDevicePrivate>();
SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
if (!dev) {
destroy_dummy(si);
return SoundIoErrorNoMem;
@ -446,7 +446,7 @@ int soundio_dummy_init(SoundIoPrivate *si) {
// create input device
{
SoundIoDevicePrivate *dev = create<SoundIoDevicePrivate>();
SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
if (!dev) {
destroy_dummy(si);
return SoundIoErrorNoMem;

View file

@ -74,9 +74,9 @@ static void destruct_device(SoundIoDevicePrivate *dp) {
SoundIoDeviceJack *dj = &dp->backend_data.jack;
for (int i = 0; i < dj->port_count; i += 1) {
SoundIoDeviceJackPort *djp = &dj->ports[i];
destroy(djp->full_name);
free(djp->full_name);
}
deallocate(dj->ports, dj->port_count);
free(dj->ports);
}
static int refresh_devices_bare(SoundIoPrivate *si) {
@ -87,7 +87,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
return SoundIoErrorBackendDisconnected;
SoundIoDevicesInfo *devices_info = create<SoundIoDevicesInfo>();
SoundIoDevicesInfo *devices_info = allocate<SoundIoDevicesInfo>(1);
if (!devices_info)
return SoundIoErrorNoMem;
@ -95,7 +95,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
devices_info->default_input_index = -1;
const char **port_names = jack_get_ports(sij->client, nullptr, nullptr, 0);
if (!port_names) {
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
@ -109,7 +109,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
// This refresh devices scan is already outdated. Just give up and
// let refresh_devices be called again.
jack_free(port_names);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorInterrupted;
}
@ -138,7 +138,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
client_name, client_name_len);
if (!client) {
jack_free(port_names);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
if (client->port_count >= SOUNDIO_MAX_CHANNELS) {
@ -164,10 +164,10 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
if (client->port_count <= 0)
continue;
SoundIoDevicePrivate *dev = create<SoundIoDevicePrivate>();
SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
if (!dev) {
jack_free(port_names);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
SoundIoDevice *device = &dev->pub;
@ -188,9 +188,9 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
device->id = soundio_str_dupe(client->name, client->name_len);
device->name = allocate<char>(description_len);
device->layout_count = 1;
device->layouts = create<SoundIoChannelLayout>();
device->layouts = allocate<SoundIoChannelLayout>(1);
device->format_count = 1;
device->formats = create<SoundIoFormat>();
device->formats = allocate<SoundIoFormat>(1);
device->current_format = SoundIoFormatFloat32NE;
device->sample_rate_min = sij->sample_rate;
device->sample_rate_max = sij->sample_rate;
@ -207,7 +207,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
if (!device->id || !device->name || !device->layouts || !device->formats || !dj->ports) {
jack_free(port_names);
soundio_device_unref(device);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
@ -221,7 +221,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
if (!djp->full_name) {
jack_free(port_names);
soundio_device_unref(device);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}
}
@ -271,7 +271,7 @@ static int refresh_devices_bare(SoundIoPrivate *si) {
if (device_list->append(device)) {
soundio_device_unref(device);
destroy(devices_info);
soundio_destroy_devices_info(devices_info);
return SoundIoErrorNoMem;
}

View file

@ -16,7 +16,7 @@
template<typename T>
struct SoundIoList {
void deinit() {
deallocate(items, capacity);
free(items);
}
int __attribute__((warn_unused_result)) append(T item) {
int err = ensure_capacity(length + 1);
@ -74,7 +74,7 @@ struct SoundIoList {
while (better_capacity < new_capacity)
better_capacity = better_capacity * 2;
if (better_capacity != capacity) {
T *new_items = reallocate_nonzero(items, capacity, better_capacity);
T *new_items = reallocate_nonzero(items, better_capacity);
if (!new_items)
return SoundIoErrorNoMem;
items = new_items;

View file

@ -191,7 +191,7 @@ int soundio_os_thread_create(
{
*out_thread = NULL;
struct SoundIoOsThread *thread = create<SoundIoOsThread>();
struct SoundIoOsThread *thread = allocate<SoundIoOsThread>(1);
if (!thread) {
soundio_os_thread_destroy(thread);
return SoundIoErrorNoMem;
@ -279,13 +279,13 @@ void soundio_os_thread_destroy(struct SoundIoOsThread *thread) {
}
#endif
destroy(thread);
free(thread);
}
struct SoundIoOsMutex *soundio_os_mutex_create(void) {
int err;
struct SoundIoOsMutex *mutex = create<SoundIoOsMutex>();
struct SoundIoOsMutex *mutex = allocate<SoundIoOsMutex>(1);
if (!mutex) {
soundio_os_mutex_destroy(mutex);
return NULL;
@ -316,7 +316,7 @@ void soundio_os_mutex_destroy(struct SoundIoOsMutex *mutex) {
}
#endif
destroy(mutex);
free(mutex);
}
void soundio_os_mutex_lock(struct SoundIoOsMutex *mutex) {
@ -336,7 +336,7 @@ void soundio_os_mutex_unlock(struct SoundIoOsMutex *mutex) {
}
struct SoundIoOsCond * soundio_os_cond_create(void) {
struct SoundIoOsCond *cond = create<SoundIoOsCond>();
struct SoundIoOsCond *cond = allocate<SoundIoOsCond>(1);
if (!cond) {
soundio_os_cond_destroy(cond);
@ -399,7 +399,7 @@ void soundio_os_cond_destroy(struct SoundIoOsCond *cond) {
}
#endif
destroy(cond);
free(cond);
}
void soundio_os_cond_signal(struct SoundIoOsCond *cond,

View file

@ -272,7 +272,7 @@ static void sink_info_callback(pa_context *pulse_context, const pa_sink_info *in
sipa->have_sink_list = true;
finish_device_query(si);
} else if (!sipa->device_query_err) {
SoundIoDevicePrivate *dev = create<SoundIoDevicePrivate>();
SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
if (!dev) {
sipa->device_query_err = SoundIoErrorNoMem;
pa_threaded_mainloop_signal(sipa->main_loop, 0);
@ -342,7 +342,7 @@ static void source_info_callback(pa_context *pulse_context, const pa_source_info
sipa->have_source_list = true;
finish_device_query(si);
} else if (!sipa->device_query_err) {
SoundIoDevicePrivate *dev = create<SoundIoDevicePrivate>();
SoundIoDevicePrivate *dev = allocate<SoundIoDevicePrivate>(1);
if (!dev) {
sipa->device_query_err = SoundIoErrorNoMem;
pa_threaded_mainloop_signal(sipa->main_loop, 0);
@ -433,7 +433,7 @@ static int scan_devices(SoundIoPrivate *si) {
sipa->have_source_list = false;
soundio_destroy_devices_info(sipa->current_devices_info);
sipa->current_devices_info = create<SoundIoDevicesInfo>();
sipa->current_devices_info = allocate<SoundIoDevicesInfo>(1);
if (!sipa->current_devices_info)
return SoundIoErrorNoMem;

View file

@ -12,7 +12,7 @@
#include <stdlib.h>
struct SoundIoRingBuffer *soundio_ring_buffer_create(struct SoundIo *soundio, int requested_capacity) {
SoundIoRingBuffer *rb = create<SoundIoRingBuffer>();
SoundIoRingBuffer *rb = allocate<SoundIoRingBuffer>(1);
assert(requested_capacity > 0);
@ -35,7 +35,7 @@ void soundio_ring_buffer_destroy(struct SoundIoRingBuffer *rb) {
soundio_ring_buffer_deinit(rb);
destroy(rb);
free(rb);
}
int soundio_ring_buffer_capacity(struct SoundIoRingBuffer *rb) {

View file

@ -149,7 +149,7 @@ void soundio_destroy(struct SoundIo *soundio) {
soundio_disconnect(soundio);
destroy(si);
free(si);
}
static void do_nothing_cb(struct SoundIo *) { }
@ -163,7 +163,7 @@ struct SoundIo *soundio_create(void) {
int err;
if ((err = soundio_os_init()))
return nullptr;
struct SoundIoPrivate *si = create<SoundIoPrivate>();
struct SoundIoPrivate *si = allocate<SoundIoPrivate>(1);
if (!si)
return nullptr;
SoundIo *soundio = &si->pub;
@ -325,10 +325,10 @@ void soundio_device_unref(struct SoundIoDevice *device) {
free(device->id);
free(device->name);
deallocate(device->formats, device->format_count);
deallocate(device->layouts, device->layout_count);
free(device->formats);
free(device->layouts);
destroy(dev);
free(dev);
}
}
@ -369,7 +369,7 @@ static void default_outstream_error_callback(struct SoundIoOutStream *os, int er
static void default_underflow_callback(struct SoundIoOutStream *outstream) { }
struct SoundIoOutStream *soundio_outstream_create(struct SoundIoDevice *device) {
SoundIoOutStreamPrivate *os = create<SoundIoOutStreamPrivate>();
SoundIoOutStreamPrivate *os = allocate<SoundIoOutStreamPrivate>(1);
if (!os)
return nullptr;
SoundIoOutStream *outstream = &os->pub;
@ -432,7 +432,7 @@ void soundio_outstream_destroy(SoundIoOutStream *outstream) {
si->outstream_destroy(si, os);
soundio_device_unref(outstream->device);
destroy(os);
free(os);
}
int soundio_outstream_start(struct SoundIoOutStream *outstream) {
@ -454,7 +454,7 @@ static void default_instream_error_callback(struct SoundIoInStream *is, int err)
}
struct SoundIoInStream *soundio_instream_create(struct SoundIoDevice *device) {
SoundIoInStreamPrivate *is = create<SoundIoInStreamPrivate>();
SoundIoInStreamPrivate *is = allocate<SoundIoInStreamPrivate>(1);
if (!is)
return nullptr;
SoundIoInStream *instream = &is->pub;
@ -522,7 +522,7 @@ void soundio_instream_destroy(struct SoundIoInStream *instream) {
si->instream_destroy(si, is);
soundio_device_unref(instream->device);
destroy(is);
free(is);
}
int soundio_instream_pause(struct SoundIoInStream *instream, bool pause) {
@ -560,7 +560,7 @@ void soundio_destroy_devices_info(SoundIoDevicesInfo *devices_info) {
devices_info->input_devices.deinit();
devices_info->output_devices.deinit();
destroy(devices_info);
free(devices_info);
}
bool soundio_have_backend(SoundIoBackend backend) {

View file

@ -11,73 +11,20 @@
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <new>
template<typename T>
__attribute__((malloc)) static inline T *allocate_nonzero(size_t count) {
T *ptr = reinterpret_cast<T*>(malloc(count * sizeof(T)));
if (ptr) {
for (size_t i = 0; i < count; i++)
new (&ptr[i]) T;
}
return ptr;
return reinterpret_cast<T*>(malloc(count * sizeof(T)));
}
template<typename T>
__attribute__((malloc)) static inline T *allocate(size_t count) {
T *ptr = reinterpret_cast<T*>(calloc(count, sizeof(T)));
if (ptr) {
for (size_t i = 0; i < count; i++)
new (&ptr[i]) T;
}
return ptr;
return reinterpret_cast<T*>(calloc(count, sizeof(T)));
}
template<typename T>
static inline T * reallocate_nonzero(T * old, size_t old_count, size_t new_count) {
assert(old_count <= new_count);
T * new_ptr = reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
if (new_ptr) {
for (size_t i = old_count; i < new_count; i += 1)
new (&new_ptr[i]) T;
}
return new_ptr;
}
template<typename T>
static inline void deallocate(T * ptr, size_t count) {
if (ptr) {
for (size_t i = 0; i < count; i += 1)
ptr[i].~T();
}
// keep this outside the if so that the if statement can be optimized out
// completely if T has no destructor
free(ptr);
}
template<typename T, typename... Args>
__attribute__((malloc)) static inline T * create_nonzero(Args... args) {
T * ptr = reinterpret_cast<T*>(malloc(sizeof(T)));
if (ptr)
new (ptr) T(args...);
return ptr;
}
template<typename T, typename... Args>
__attribute__((malloc)) static inline T * create(Args... args) {
T * ptr = reinterpret_cast<T*>(calloc(1, sizeof(T)));
if (ptr)
new (ptr) T(args...);
return ptr;
}
template<typename T>
static inline void destroy(T * ptr) {
if (ptr)
ptr[0].~T();
// keep this outside the if so that the if statement can be optimized out
// completely if T has no destructor
free(ptr);
static inline T *reallocate_nonzero(T * old, size_t new_count) {
return reinterpret_cast<T*>(realloc(old, new_count * sizeof(T)));
}
void soundio_panic(const char *format, ...)