mirror of
https://github.com/ByteWelder/Tactility.git
synced 2026-02-18 19:03:16 +00:00
added cmsis_core, furi, mlib and nanobake implemented basic app structure from furi implemented basic placeholder apps
521 lines
36 KiB
C
521 lines
36 KiB
C
/*
|
|
* M*LIB - dynamic priority queue module
|
|
*
|
|
* Copyright (c) 2017-2023, Patrick Pelissier
|
|
* All rights reserved.
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* + Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* + Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
#ifndef MSTARLIB_PRIOQUEUE_H
|
|
#define MSTARLIB_PRIOQUEUE_H
|
|
|
|
#include "m-core.h"
|
|
#include "m-array.h" /* Priority queue are built upon array */
|
|
|
|
/* Priority queue based on binary heap implementation */
|
|
|
|
/* Define a prioqueue of a given type and its associated functions.
|
|
USAGE: PRIOQUEUE_DEF(name, type [, oplist_of_the_type]) */
|
|
#define M_PRIOQUEUE_DEF(name, ...) \
|
|
M_PRIOQUEUE_DEF_AS(name, M_F(name,_t), M_F(name,_it_t), __VA_ARGS__)
|
|
|
|
|
|
/* Define a prioqueue of a given type and its associated functions.
|
|
as the name name_t with an iterator named it_t
|
|
USAGE: PRIOQUEUE_DEF_AS(name, name_t, it_t, type [, oplist_of_the_type]) */
|
|
#define M_PRIOQUEUE_DEF_AS(name, name_t, it_t, ...) \
|
|
M_BEGIN_PROTECTED_CODE \
|
|
M_PR1OQUEUE_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \
|
|
((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), name_t, it_t ), \
|
|
(name, __VA_ARGS__, name_t, it_t ))) \
|
|
M_END_PROTECTED_CODE
|
|
|
|
|
|
/* Define the oplist of a prioqueue of type.
|
|
USAGE: PRIOQUEUE_OPLIST(name[, oplist of the type]) */
|
|
#define M_PRIOQUEUE_OPLIST(...) \
|
|
M_PR1OQUEUE_OPLIST_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \
|
|
((__VA_ARGS__, M_BASIC_OPLIST), \
|
|
(__VA_ARGS__ )))
|
|
|
|
|
|
/*****************************************************************************/
|
|
/********************************** INTERNAL *********************************/
|
|
/*****************************************************************************/
|
|
|
|
/* Deferred evaluation for the definition,
|
|
so that all arguments are evaluated before further expansion */
|
|
#define M_PR1OQUEUE_OPLIST_P1(arg) M_PR1OQUEUE_OPLIST_P2 arg
|
|
|
|
/* Validation of the given oplist */
|
|
#define M_PR1OQUEUE_OPLIST_P2(name, oplist) \
|
|
M_IF_OPLIST(oplist)(M_PR1OQUEUE_OPLIST_P3, M_PR1OQUEUE_OPLIST_FAILURE)(name, oplist)
|
|
|
|
/* Prepare a clean compilation failure */
|
|
#define M_PR1OQUEUE_OPLIST_FAILURE(name, oplist) \
|
|
((M_LIB_ERROR(ARGUMENT_OF_PRIOQUEUE_OPLIST_IS_NOT_AN_OPLIST, name, oplist)))
|
|
|
|
/* Define oplist of a priority queue */
|
|
#define M_PR1OQUEUE_OPLIST_P3(name, oplist) \
|
|
(INIT(M_F(name, _init)) \
|
|
,INIT_SET(M_F(name, _init_set)) \
|
|
,INIT_WITH(API_1(M_INIT_VAI)) \
|
|
,SET(M_F(name, _set)) \
|
|
,CLEAR(M_F(name, _clear)) \
|
|
,INIT_MOVE(M_F(name, _init_move)) \
|
|
,MOVE(M_F(name, _move)) \
|
|
,SWAP(M_F(name, _swap)) \
|
|
,NAME(name) \
|
|
,TYPE(M_F(name,_ct)) \
|
|
,SUBTYPE(M_F(name, _subtype_ct)) \
|
|
,RESET(M_F(name,_reset)) \
|
|
,PUSH(M_F(name,_push)) \
|
|
,POP(M_F(name,_pop)) \
|
|
,OPLIST(oplist) \
|
|
,EMPTY_P(M_F(name, _empty_p)) \
|
|
,GET_SIZE(M_F(name, _size)) \
|
|
,IT_TYPE(M_F(name, _it_ct)) \
|
|
,IT_FIRST(M_F(name,_it)) \
|
|
,IT_END(M_F(name,_it_end)) \
|
|
,IT_SET(M_F(name,_it_set)) \
|
|
,IT_END_P(M_F(name,_end_p)) \
|
|
,IT_EQUAL_P(M_F(name,_it_equal_p)) \
|
|
,IT_LAST_P(M_F(name,_last_p)) \
|
|
,IT_NEXT(M_F(name,_next)) \
|
|
,IT_CREF(M_F(name,_cref)) \
|
|
,M_IF_METHOD(GET_STR, oplist)(GET_STR(M_F(name, _get_str)),) \
|
|
,M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_F(name, _parse_str)),) \
|
|
,M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_F(name, _out_str)),) \
|
|
,M_IF_METHOD(IN_STR, oplist)(IN_STR(M_F(name, _in_str)),) \
|
|
,M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_F(name, _out_serial)),) \
|
|
,M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_F(name, _in_serial)),) \
|
|
)
|
|
|
|
|
|
/********************************** INTERNAL *********************************/
|
|
|
|
/* Deferred evaluation for the definition,
|
|
so that all arguments are evaluated before further expansion */
|
|
#define M_PR1OQUEUE_DEF_P1(arg) M_ID( M_PR1OQUEUE_DEF_P2 arg )
|
|
|
|
/* Validate the oplist before going further */
|
|
#define M_PR1OQUEUE_DEF_P2(name, type, oplist, prioqueue_t, it_t) \
|
|
M_IF_OPLIST(oplist)(M_PR1OQUEUE_DEF_P3, M_PR1OQUEUE_DEF_FAILURE)(name, type, oplist, prioqueue_t, it_t)
|
|
|
|
/* Stop processing with a compilation failure */
|
|
#define M_PR1OQUEUE_DEF_FAILURE(name, type, oplist, prioqueue_t, it_t) \
|
|
M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(PRIOQUEUE_DEF): the given argument is not a valid oplist: " #oplist)
|
|
|
|
/* Define the priority queue:
|
|
- name: prefix to use,
|
|
- type: type of the contained objects,
|
|
- oplist: oplist of the contained objects,
|
|
- prioqueue_t: type of the container,
|
|
- it_t: iterator of the container
|
|
*/
|
|
#define M_PR1OQUEUE_DEF_P3(name, type, oplist, prioqueue_t, it_t) \
|
|
/* Definition of the internal array used to construct the priority queue */ \
|
|
ARRAY_DEF(M_F(name, _array), type, oplist) \
|
|
M_PR1OQUEUE_DEF_TYPE(name, type, oplist, prioqueue_t, it_t) \
|
|
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
|
|
M_PR1OQUEUE_DEF_CORE(name, type, oplist, prioqueue_t, it_t) \
|
|
M_PR1OQUEUE_DEF_IT(name, type, oplist, prioqueue_t, it_t) \
|
|
M_PR1OQUEUE_DEF_IO(name, type, oplist, prioqueue_t, it_t) \
|
|
M_EMPLACE_QUEUE_DEF(name, prioqueue_t, M_F(name, _emplace), oplist, M_EMPLACE_QUEUE_GENE)
|
|
|
|
/* Define the types */
|
|
#define M_PR1OQUEUE_DEF_TYPE(name, type, oplist, prioqueue_t, it_t) \
|
|
\
|
|
/* Define the priority queue over the defined array */ \
|
|
typedef struct M_F(name, _s) { \
|
|
M_F(name, _array_t) array; \
|
|
} prioqueue_t[1]; \
|
|
/* Define the pointer references to the priority queue */ \
|
|
typedef struct M_F(name, _s) *M_F(name, _ptr); \
|
|
typedef const struct M_F(name, _s) *M_F(name, _srcptr); \
|
|
\
|
|
/* The iterator is the same one as the one of the internal array */ \
|
|
typedef M_F(name, _array_it_t) it_t; \
|
|
\
|
|
/* Definition of the internal types used by the oplist */ \
|
|
typedef prioqueue_t M_F(name, _ct); \
|
|
typedef type M_F(name, _subtype_ct); \
|
|
typedef it_t M_F(name, _it_ct); \
|
|
|
|
/* Define the core functions */
|
|
#define M_PR1OQUEUE_DEF_CORE(name, type, oplist, prioqueue_t, it_t) \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _init)(prioqueue_t p) \
|
|
{ \
|
|
M_F(name, _array_init)(p->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _init_set)(prioqueue_t p, prioqueue_t const o) \
|
|
{ \
|
|
M_F(name, _array_init_set)(p->array, o->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _set)(prioqueue_t p, prioqueue_t const o) \
|
|
{ \
|
|
M_F(name, _array_set)(p->array, o->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _clear)(prioqueue_t p) \
|
|
{ \
|
|
M_F(name, _array_clear)(p->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _init_move)(prioqueue_t p, prioqueue_t o) \
|
|
{ \
|
|
M_F(name, _array_init_move)(p->array, o->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _move)(prioqueue_t p, prioqueue_t o) \
|
|
{ \
|
|
M_F(name, _array_move)(p->array, o->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _swap)(prioqueue_t p, prioqueue_t o) \
|
|
{ \
|
|
M_F(name, _array_swap)(p->array, o->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _reset)(prioqueue_t p) \
|
|
{ \
|
|
M_F(name, _array_reset)(p->array); \
|
|
} \
|
|
\
|
|
M_INLINE size_t \
|
|
M_F(name, _i_parent)(size_t i) \
|
|
{ \
|
|
M_ASSERT (i > 0); \
|
|
return (i - 1) / 2; \
|
|
} \
|
|
\
|
|
M_INLINE size_t \
|
|
M_F(name, _i_lchild)(size_t i) \
|
|
{ \
|
|
M_ASSERT(i <= ((SIZE_MAX)-2)/2); \
|
|
return 2*i + 1; \
|
|
} \
|
|
\
|
|
M_INLINE size_t \
|
|
M_F(name, _i_rchild)(size_t i) \
|
|
{ \
|
|
M_ASSERT(i <= ((SIZE_MAX)-2)/2); \
|
|
return 2*i + 2; \
|
|
} \
|
|
\
|
|
M_INLINE int \
|
|
M_F(name, _i_cmp)(const prioqueue_t p, size_t i, size_t j) \
|
|
{ \
|
|
return M_CALL_CMP(oplist, *M_F(name, _array_cget)(p->array, i), \
|
|
*M_F(name, _array_cget)(p->array, j)); \
|
|
} \
|
|
\
|
|
M_INLINE bool \
|
|
M_F(name, _empty_p)(prioqueue_t const p) \
|
|
{ \
|
|
return M_F(name, _array_empty_p)(p->array); \
|
|
} \
|
|
\
|
|
M_INLINE size_t \
|
|
M_F(name, _size)(prioqueue_t const p) \
|
|
{ \
|
|
return M_F(name, _array_size)(p->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _push)(prioqueue_t p, type const x) \
|
|
{ \
|
|
/* Push back the new element at the end of the array */ \
|
|
M_F(name, _array_push_back)(p->array, x); \
|
|
\
|
|
/* Reorder the array by swapping with its parent \
|
|
* until it reaches the right position */ \
|
|
size_t i = M_F(name, _array_size)(p->array)-1; \
|
|
while (i > 0) { \
|
|
size_t j = M_F(name, _i_parent)(i); \
|
|
if (M_F(name, _i_cmp)(p, j, i) <= 0) \
|
|
break; \
|
|
M_F(name, _array_swap_at) (p->array, i, j); \
|
|
i = j; \
|
|
} \
|
|
} \
|
|
\
|
|
M_INLINE type const * \
|
|
M_F(name, _front)(prioqueue_t const p) \
|
|
{ \
|
|
return M_F(name, _array_cget)(p->array, 0); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _pop)(type *x, prioqueue_t p) \
|
|
{ \
|
|
/* Swap the front element with the last element */ \
|
|
size_t size = M_F(name, _array_size)(p->array)-1; \
|
|
M_F(name, _array_swap_at) (p->array, 0, size); \
|
|
/* Swap the new last element */ \
|
|
M_F(name, _array_pop_back)(x, p->array); \
|
|
\
|
|
/* Reorder the heap */ \
|
|
size_t i = 0; \
|
|
while (true) { \
|
|
size_t child = M_F(name, _i_lchild)(i); \
|
|
if (child >= size) \
|
|
break; \
|
|
size_t otherChild = M_F(name, _i_rchild)(i); \
|
|
if (otherChild < size \
|
|
&& M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
|
|
child = otherChild; \
|
|
} \
|
|
if (M_F(name, _i_cmp)(p, i, child) <= 0) \
|
|
break; \
|
|
M_F(name, _array_swap_at) (p->array, i, child); \
|
|
i = child; \
|
|
} \
|
|
} \
|
|
\
|
|
M_IF_METHOD(EQUAL, oplist) \
|
|
( \
|
|
/* EQUAL & CMP may be uncorrelated */ \
|
|
M_INLINE bool \
|
|
M_F(name, _equal_p)(prioqueue_t const p, prioqueue_t const q) \
|
|
{ \
|
|
return M_F(name, _array_equal_p)(p->array, q->array); \
|
|
} \
|
|
\
|
|
M_INLINE size_t \
|
|
M_F(name, _i_find)(prioqueue_t p, type const x) \
|
|
{ \
|
|
size_t size = M_F(name, _array_size)(p->array); \
|
|
size_t i = 0; \
|
|
for(i = 0; i < size; i++) { \
|
|
/* We cannot use CMP and the partial order to go faster \
|
|
EQUAL & CMP may be uncorrelated */ \
|
|
if (M_CALL_EQUAL(oplist, *M_F(name, _array_cget)(p->array, i), x)) \
|
|
break; \
|
|
} \
|
|
return i; \
|
|
} \
|
|
\
|
|
M_INLINE bool \
|
|
M_F(name, _erase)(prioqueue_t p, type const x) \
|
|
{ \
|
|
/* First pass: search for an item EQUAL to x */ \
|
|
size_t size = M_F(name, _array_size)(p->array); \
|
|
size_t i = M_F(name, _i_find)(p, x); \
|
|
/* If x is not found, then stop */ \
|
|
if (i >= size) \
|
|
return false; \
|
|
/* Swap the found item and the last element */ \
|
|
size--; \
|
|
M_F(name, _array_swap_at) (p->array, i, size); \
|
|
M_F(name, _array_pop_back)(NULL, p->array); \
|
|
/* Move back the last swapped element to its right position in the heap */ \
|
|
while (true) { \
|
|
size_t child = M_F(name, _i_lchild)(i); \
|
|
if (child >= size) break; \
|
|
size_t otherChild = M_F(name, _i_rchild)(i); \
|
|
if (otherChild < size \
|
|
&& M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
|
|
child = otherChild; \
|
|
} \
|
|
if (M_F(name, _i_cmp)(p, i, child) <= 0) break; \
|
|
M_F(name, _array_swap_at) (p->array, i, child); \
|
|
i = child; \
|
|
} \
|
|
return true; \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _update)(prioqueue_t p, type const xold, type const xnew) \
|
|
{ \
|
|
/* NOTE: xold can be the same pointer than xnew */ \
|
|
/* First pass: search for an item EQUAL to x */ \
|
|
size_t size = M_F(name, _array_size)(p->array); \
|
|
size_t i = M_F(name, _i_find)(p, xold); \
|
|
/* We shall have found the item */ \
|
|
M_ASSERT (i < size); \
|
|
/* Test if the position of the old data is further or nearer than the new */ \
|
|
int cmp = M_CALL_CMP(oplist, *M_F(name, _array_cget)(p->array, i), xnew); \
|
|
/* Set the found item to the new element */ \
|
|
M_F(name, _array_set_at) (p->array, i, xnew); \
|
|
if (cmp < 0) { \
|
|
/* Move back the updated element to its new position, further in the heap */ \
|
|
while (true) { \
|
|
size_t child = M_F(name, _i_lchild)(i); \
|
|
if (child >= size) break; \
|
|
size_t otherChild = M_F(name, _i_rchild)(i); \
|
|
if (otherChild < size \
|
|
&& M_F(name, _i_cmp)(p, otherChild, child) < 0 ) { \
|
|
child = otherChild; \
|
|
} \
|
|
if (M_F(name, _i_cmp)(p, i, child) <= 0) break; \
|
|
M_F(name, _array_swap_at) (p->array, i, child); \
|
|
i = child; \
|
|
} \
|
|
} else { \
|
|
/* Move back the updated element to its new position, nearest in the heap */ \
|
|
while (i > 0) { \
|
|
size_t parent = M_F(name, _i_parent)(i); \
|
|
if (M_F(name, _i_cmp)(p, parent, i) <= 0) break; \
|
|
M_F(name, _array_swap_at) (p->array, i, parent); \
|
|
i = parent; \
|
|
} \
|
|
} \
|
|
} \
|
|
, /* No EQUAL */ ) \
|
|
|
|
/* Define the IT based functions */
|
|
#define M_PR1OQUEUE_DEF_IT(name, type, oplist, prioqueue_t, it_t) \
|
|
\
|
|
/* Define iterators over the array iterator */ \
|
|
M_INLINE void \
|
|
M_F(name, _it)(it_t it, prioqueue_t const v) \
|
|
{ \
|
|
M_F(name, _array_it)(it, v->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _it_last)(it_t it, prioqueue_t const v) \
|
|
{ \
|
|
M_F(name, _array_it_last)(it, v->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _it_end)(it_t it, prioqueue_t const v) \
|
|
{ \
|
|
M_F(name, _array_it_end)(it, v->array); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _it_set)(it_t it, const it_t org) \
|
|
{ \
|
|
M_F(name, _array_it_set)(it, org); \
|
|
} \
|
|
\
|
|
M_INLINE bool \
|
|
M_F(name, _end_p)(const it_t it) \
|
|
{ \
|
|
return M_F(name, _array_end_p)(it); \
|
|
} \
|
|
\
|
|
M_INLINE bool \
|
|
M_F(name, _last_p)(const it_t it) \
|
|
{ \
|
|
return M_F(name, _array_last_p)(it); \
|
|
} \
|
|
\
|
|
M_INLINE bool \
|
|
M_F(name, _it_equal_p)(const it_t it1, \
|
|
const it_t it2) \
|
|
{ \
|
|
return M_F(name, _array_it_equal_p)(it1, it2); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _next)(it_t it) \
|
|
{ \
|
|
M_F(name, _array_next)(it); \
|
|
} \
|
|
\
|
|
M_INLINE void \
|
|
M_F(name, _previous)(it_t it) \
|
|
{ \
|
|
M_F(name, _array_previous)(it); \
|
|
} \
|
|
\
|
|
M_INLINE type const * \
|
|
M_F(name, _cref)(const it_t it) \
|
|
{ \
|
|
return M_F(name, _array_cref)(it); \
|
|
} \
|
|
|
|
/* Define the IO functions */
|
|
#define M_PR1OQUEUE_DEF_IO(name, type, oplist, prioqueue_t, it_t) \
|
|
M_IF_METHOD(OUT_STR, oplist)( \
|
|
M_INLINE void \
|
|
M_F(name, _out_str)(FILE *file, const prioqueue_t p) \
|
|
{ \
|
|
M_F(name, _array_out_str)(file, p->array); \
|
|
} \
|
|
,/* No OUT_STR */) \
|
|
\
|
|
M_IF_METHOD(IN_STR, oplist)( \
|
|
M_INLINE bool \
|
|
M_F(name, _in_str)(prioqueue_t p, FILE *file) \
|
|
{ \
|
|
return M_F(name, _array_in_str)(p->array, file); \
|
|
} \
|
|
,/* No IN_STR */) \
|
|
\
|
|
M_IF_METHOD(GET_STR, oplist)( \
|
|
M_INLINE void \
|
|
M_F(name, _get_str)(string_t str, const prioqueue_t p, bool append) \
|
|
{ \
|
|
M_F(name, _array_get_str)(str, p->array, append); \
|
|
} \
|
|
,/* No GET_STR */) \
|
|
\
|
|
M_IF_METHOD(PARSE_STR, oplist)( \
|
|
M_INLINE bool \
|
|
M_F(name, _parse_str)(prioqueue_t p, const char str[], const char **endp) \
|
|
{ \
|
|
return M_F(name, _array_parse_str)(p->array, str, endp); \
|
|
} \
|
|
,/* No PARSE_STR */) \
|
|
\
|
|
M_IF_METHOD(OUT_SERIAL, oplist)( \
|
|
M_INLINE m_serial_return_code_t \
|
|
M_F(name, _out_serial)(m_serial_write_t f, const prioqueue_t p) \
|
|
{ \
|
|
return M_F(name, _array_out_serial)(f, p->array); \
|
|
} \
|
|
,/* No OUT_SERIAL */) \
|
|
\
|
|
M_IF_METHOD2(IN_SERIAL, INIT, oplist)( \
|
|
M_INLINE m_serial_return_code_t \
|
|
M_F(name, _in_serial)(prioqueue_t p, m_serial_read_t f) \
|
|
{ \
|
|
return M_F(name, _array_in_serial)(p->array, f); \
|
|
} \
|
|
,/* No in_SERIAL */) \
|
|
|
|
|
|
// TODO: set all & remove all function
|
|
|
|
/********************************** INTERNAL *********************************/
|
|
|
|
#if M_USE_SMALL_NAME
|
|
#define PRIOQUEUE_DEF M_PRIOQUEUE_DEF
|
|
#define PRIOQUEUE_DEF_AS M_PRIOQUEUE_DEF_AS
|
|
#define PRIOQUEUE_OPLIST M_PRIOQUEUE_OPLIST
|
|
#endif
|
|
|
|
#endif
|