u/deque: Add generic wrapper for std::deque

This commit is contained in:
Mateo de Mayo 2022-07-20 11:39:29 -03:00 committed by Moses Turner
parent a7e62432b5
commit ae8305f324
5 changed files with 158 additions and 0 deletions

View file

@ -17,6 +17,8 @@ add_library(
u_builders.h
u_debug.c
u_debug.h
u_deque.cpp
u_deque.h
u_device.c
u_device.h
u_distortion.c

View file

@ -0,0 +1,61 @@
// Copyright 2022, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Expose std::deque to C
* @author Mateo de Mayo <mateo.demayo@collabora.com>
* @ingroup aux_util
*/
#include "u_deque.h"
#include "util/u_time.h"
#include <deque>
using std::deque;
#define U_DEQUE_IMPLEMENTATION(TYPE) \
u_deque_##TYPE u_deque_##TYPE##_create() \
{ \
u_deque_##TYPE ud{new deque<TYPE>}; \
return ud; \
} \
\
void u_deque_##TYPE##_push_back(u_deque_##TYPE ud, TYPE e) \
{ \
deque<TYPE> *d = static_cast<deque<TYPE> *>(ud.ptr); \
d->push_back(e); \
} \
\
bool u_deque_##TYPE##_pop_front(u_deque_##TYPE ud, TYPE *e) \
{ \
deque<TYPE> *d = static_cast<deque<TYPE> *>(ud.ptr); \
bool pop = !d->empty(); \
if (pop) { \
*e = d->front(); \
d->erase(d->begin()); \
} \
return pop; \
} \
\
TYPE u_deque_##TYPE##_at(u_deque_##TYPE ud, size_t i) \
{ \
deque<TYPE> *d = static_cast<deque<TYPE> *>(ud.ptr); \
return d->at(i); \
} \
\
size_t u_deque_##TYPE##_size(u_deque_##TYPE ud) \
{ \
deque<TYPE> *d = static_cast<deque<TYPE> *>(ud.ptr); \
return d->size(); \
} \
\
void u_deque_##TYPE##_destroy(u_deque_##TYPE *ud) \
{ \
deque<TYPE> *d = static_cast<deque<TYPE> *>(ud->ptr); \
delete d; \
ud->ptr = nullptr; \
}
extern "C" {
U_DEQUE_IMPLEMENTATION(timepoint_ns)
}

View file

@ -0,0 +1,35 @@
// Copyright 2022, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Expose std::deque to C
* @author Mateo de Mayo <mateo.demayo@collabora.com>
* @ingroup aux_util
*/
#pragma once
#include "util/u_time.h"
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
#define U_DEQUE_DECLARATION(TYPE) \
struct u_deque_##TYPE \
{ \
void *ptr; \
}; \
struct u_deque_##TYPE u_deque_##TYPE##_create(); \
void u_deque_##TYPE##_push_back(struct u_deque_##TYPE ud, TYPE e); \
bool u_deque_##TYPE##_pop_front(struct u_deque_##TYPE ud, TYPE *e); \
TYPE u_deque_##TYPE##_at(struct u_deque_##TYPE ud, size_t i); \
size_t u_deque_##TYPE##_size(struct u_deque_##TYPE wrap); \
void u_deque_##TYPE##_destroy(struct u_deque_##TYPE *ud);
U_DEQUE_DECLARATION(timepoint_ns)
#ifdef __cplusplus
}
#endif

View file

@ -11,6 +11,7 @@ endif()
set(tests
tests_cxx_wrappers
tests_deque
tests_generic_callbacks
tests_history_buf
tests_id_ringbuffer

59
tests/tests_deque.cpp Normal file
View file

@ -0,0 +1,59 @@
// Copyright 2022, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Test u_deque C interface.
* @author Mateo de Mayo <mateo.demayo@collabora.com>
*/
#include "catch/catch.hpp"
#include "util/u_deque.h"
TEST_CASE("u_deque")
{
SECTION("Test interface generated from macros")
{
struct u_deque_timepoint_ns dt = u_deque_timepoint_ns_create();
CHECK(dt.ptr != NULL);
constexpr timepoint_ns A = 11111111;
constexpr timepoint_ns B = 22222222;
constexpr timepoint_ns C = 33333333;
timepoint_ns elem = 0;
CHECK(!u_deque_timepoint_ns_pop_front(dt, &elem));
CHECK(elem == 0);
u_deque_timepoint_ns_push_back(dt, C);
u_deque_timepoint_ns_push_back(dt, A);
CHECK(u_deque_timepoint_ns_pop_front(dt, &elem));
CHECK(elem == C);
CHECK(u_deque_timepoint_ns_size(dt) == 1);
u_deque_timepoint_ns_push_back(dt, B);
u_deque_timepoint_ns_push_back(dt, C);
timepoint_ns a = u_deque_timepoint_ns_at(dt, 0);
timepoint_ns b = u_deque_timepoint_ns_at(dt, 1);
timepoint_ns c = u_deque_timepoint_ns_at(dt, 2);
CHECK(a == A);
CHECK(b == B);
CHECK(c == C);
CHECK(u_deque_timepoint_ns_size(dt) == 3);
CHECK(u_deque_timepoint_ns_pop_front(dt, &elem));
CHECK(elem == A);
CHECK(u_deque_timepoint_ns_pop_front(dt, &elem));
CHECK(elem == B);
CHECK(u_deque_timepoint_ns_pop_front(dt, &elem));
CHECK(elem == C);
CHECK(u_deque_timepoint_ns_size(dt) == 0);
u_deque_timepoint_ns_destroy(&dt);
CHECK(dt.ptr == NULL);
}
}