Type agnostic, statically allocated queue in C

I need a queue in C for an embedded application in which I cannot allocate memory dynamically.

Using void* for the queue elements is not convenient lifecycle-wise so to make it reusable, some macros had to (?) come from the #includer. One thing led to another and now I have to include the *.c file rather than the *.h file to compile user code.

user_code.c:

typedef struct custom_t
{
    /* whatever */
} custom_t;

#define QUEUE_MAX_CAPACITY 5
#define QUEUE_ELEMENT_TYPE struct custom_t
#include "typed_queue.c" /* NOTE using ".c" file */

queue_t queue;
/* now use queue to do stuff */

typed_queue.h:

#ifndef INCLUDE_GUARD_TYPED_QUEUE_H
#define INCLUDE_GUARD_TYPED_QUEUE_H

#include <stddef.h>
#include <stdbool.h>

/* 
The following macros must be defined by the #includer:
 - QUEUE_MAX_CAPACITY
 - QUEUE_ELEMENT_TYPE 
*/

#define QUEUE_SIZE (QUEUE_MAX_CAPACITY + 1)
typedef QUEUE_ELEMENT_TYPE element_t;

typedef struct queue_t
{
    size_t in;
    size_t out;
    element_t elements(QUEUE_SIZE);
} queue_t;

void queue_init(queue_t*);

/* return true on success */
bool queue_push(queue_t*, element_t*); /* might add queue_push_byval() */
bool queue_pop(queue_t*, element_t*);
/* also have queue_front, queue_back, queue_size */

bool queue_empty(queue_t const *);
bool queue_full(queue_t const *);

#endif // INCLUDE_GUARD_TYPED_QUEUE_H

typed_queue.c:

#ifndef INCLUDE_GUARD_TYPED_QUEUE_C
#define INCLUDE_GUARD_TYPED_QUEUE_C

#include "typed_queue.h"

/* the usual stuff */

#endif // INCLUDE_GUARD_TYPED_QUEUE_C