6 n__stack_8h
gullradriel edited this page 2026-10-09 00:55:18 +02:00

include/nilorea/n_stack.h

Stack header definitions. More...

Structures

Name
struct STACK_ITEM
structure of a STACK item
union STACK_DATA
structure of a STACK_ITEM data
struct STACK
STACK structure.

Detailed Description

Stack header definitions.

Author: Castagnier Mickael

Version: 2.0

Date: 01/01/2018

Source code

/*
 * Nilorea Library
 * Copyright (C) 2005-2026 Castagnier Mickael
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#ifndef __N_STACK_HEADER
#define __N_STACK_HEADER

#ifdef __cplusplus
extern "C" {
#endif


#include "nilorea/n_common.h"

#define STACK_ITEM_BOOL 1
#define STACK_ITEM_CHAR 2
#define STACK_ITEM_UINT8 3
#define STACK_ITEM_INT8 4
#define STACK_ITEM_UINT32 5
#define STACK_ITEM_INT32 6
#define STACK_ITEM_UINT64 7
#define STACK_ITEM_INT64 8
#define STACK_ITEM_FLOAT 9
#define STACK_ITEM_DOUBLE 10
#define STACK_ITEM_PTR 11

#define STACK_IS_FULL 0
#define STACK_IS_EMPTY 1
#define STACK_IS_UNDEFINED 2
#define STACK_ITEM_WRONG_TYPE 3
#define STACK_ITEM_OK 4

union STACK_DATA {
    bool b;
    char c;
    uint8_t ui8;
    int8_t i8;
    uint32_t ui32;
    int32_t i32;
#ifdef ENV_64BITS
    uint64_t ui64;
    int64_t i64;
#endif
    float f;
    double d;
    void* p;
};

typedef struct STACK_ITEM {
    bool is_set;
    bool is_empty;
    union STACK_DATA data;
    uint8_t v_type;
    uint16_t p_type;
} STACK_ITEM;

typedef struct STACK {
    STACK_ITEM* stack_array;
    size_t size;
    size_t head;
    size_t tail;
    size_t nb_items;
} STACK;

/* stack_push_p_default is declared below with the other push functions.
 * It wraps stack_push_p with a default p_type of 0 so the _Generic macro
 * can dispatch void* with only 2 arguments.
 * Use stack_push_p() directly when a custom p_type is needed. */

#if defined(__sun) && defined(__SVR4)
/* Solaris: avoid _Generic conflicts due to type compatibility */
#ifdef ENV_64BITS
#define stack_push(__STACK, __VAL)                            \
    _Generic((__VAL),                                         \
        bool: stack_push_b,                                   \
        char: stack_push_c,                                   \
        signed char: stack_push_i8,    /* replaces int8_t */  \
        unsigned char: stack_push_ui8, /* replaces uint8_t */ \
        uint32_t: stack_push_ui32,                            \
        int32_t: stack_push_i32,                              \
        uint64_t: stack_push_ui64,                            \
        int64_t: stack_push_i64,                              \
        float: stack_push_f,                                  \
        double: stack_push_d,                                 \
        void*: stack_push_p_default)(__STACK, __VAL)
#else
#define stack_push(__STACK, __VAL)     \
    _Generic((__VAL),                  \
        bool: stack_push_b,            \
        char: stack_push_c,            \
        signed char: stack_push_i8,    \
        unsigned char: stack_push_ui8, \
        uint32_t: stack_push_ui32,     \
        int32_t: stack_push_i32,       \
        float: stack_push_f,           \
        double: stack_push_d,          \
        void*: stack_push_p_default)(__STACK, __VAL)
#endif
#else
/* Default version for Linux, Windows, etc. */
#ifdef ENV_64BITS
#define stack_push(__STACK, __VAL) \
    _Generic((__VAL),              \
        bool: stack_push_b,        \
        char: stack_push_c,        \
        uint8_t: stack_push_ui8,   \
        int8_t: stack_push_i8,     \
        uint32_t: stack_push_ui32, \
        int32_t: stack_push_i32,   \
        uint64_t: stack_push_ui64, \
        int64_t: stack_push_i64,   \
        float: stack_push_f,       \
        double: stack_push_d,      \
        void*: stack_push_p_default)(__STACK, __VAL)
#else
#define stack_push(__STACK, __VAL) \
    _Generic((__VAL),              \
        bool: stack_push_b,        \
        char: stack_push_c,        \
        uint8_t: stack_push_ui8,   \
        int8_t: stack_push_i8,     \
        uint32_t: stack_push_ui32, \
        int32_t: stack_push_i32,   \
        float: stack_push_f,       \
        double: stack_push_d,      \
        void*: stack_push_p_default)(__STACK, __VAL)
#endif
#endif

STACK* new_stack(size_t nb_items);
bool delete_stack(STACK** stack);
bool stack_is_full(const STACK* stack);
bool stack_is_empty(const STACK* stack);
STACK_ITEM* stack_peek(STACK* stack, size_t position);

bool stack_push_b(STACK* stack, bool b);
bool stack_push_c(STACK* stack, char c);
bool stack_push_ui8(STACK* stack, uint8_t ui8);
bool stack_push_i8(STACK* stack, int8_t i8);
bool stack_push_ui32(STACK* stack, uint32_t ui32);
bool stack_push_i32(STACK* stack, int32_t i32);
bool stack_push_f(STACK* stack, float f);
bool stack_push_d(STACK* stack, double d);
bool stack_push_p(STACK* stack, void* p, uint16_t p_type);
bool stack_push_p_default(STACK* stack, void* p);

bool stack_pop_b(STACK* stack, uint8_t* status);
char stack_pop_c(STACK* stack, uint8_t* status);
uint8_t stack_pop_ui8(STACK* stack, uint8_t* status);
int8_t stack_pop_i8(STACK* stack, uint8_t* status);
uint32_t stack_pop_ui32(STACK* stack, uint8_t* status);
int32_t stack_pop_i32(STACK* stack, uint8_t* status);
float stack_pop_f(STACK* stack, uint8_t* status);
double stack_pop_d(STACK* stack, uint8_t* status);
void* stack_pop_p(STACK* stack, uint8_t* status);

#ifdef ENV_64BITS
bool stack_push_ui64(STACK* stack, uint64_t ui64_t);
bool stack_push_i64(STACK* stack, int64_t i64);
uint64_t stack_pop_ui64(STACK* stack, uint8_t* status);
int64_t stack_pop_i64(STACK* stack, uint8_t* status);
#endif


#ifdef __cplusplus
}
#endif

#endif