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

include/nilorea/n_enum.h

Macro to build enums and their tostring counterparts, a reduced version of https://github.com/FredBienvenu/SmartEnum. More...

Detailed Description

Macro to build enums and their tostring counterparts, a reduced version of https://github.com/FredBienvenu/SmartEnum.

Author: Castagnier Mickael, based on original FredBienvenu SmartEnum entry

Version: 1.0

Date: 28/09/2021

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_ENUM_HEADER__
#define __N_ENUM_HEADER__

#include <string.h>  // for strcmp
#include <stdbool.h>

#ifdef __cplusplus
extern "C" {
#endif


/* MACROS FOR N_ENUMS MACRO ENTRIES (START) */

#define N_ENUM_ENTRY(class, method) class##__##method

#define __N_ENUM_MACRO_ENTRY_CASE(element_name) case element_name:
#define __N_ENUM_MACRO_ENTRY_COMPARE(element_name) if (!strcmp(#element_name, str_value))
#define __N_ENUM_MACRO_ENTRY_COMPARE_EX(element_name) if (!strcmp(&(#element_name)[index], str_value))
#define __N_ENUM_MACRO_ENTRY_UNKNOWN_VALUE(enum_name) __##enum_name##_UNKNOWN_VALUE__

#define __N_ENUM_MACRO_ENTRY_TO_ENUM_ELEMENT(element_name, element_value) \
    element_name = element_value,
#define __N_ENUM_MACRO_ENTRY_TO_ISVALID_CASE(element_name, element_value) \
    __N_ENUM_MACRO_ENTRY_CASE(element_name)                               \
    return true;
#define __N_ENUM_MACRO_ENTRY_TO_TOSTRING_CASE(element_name, element_value) \
    __N_ENUM_MACRO_ENTRY_CASE(element_name)                                \
    return #element_name;
#define __N_ENUM_MACRO_ENTRY_TO_FROMSTRING_COMPARE(element_name, element_value) \
    __N_ENUM_MACRO_ENTRY_COMPARE(element_name)                                  \
    return element_name;
#define __N_ENUM_MACRO_ENTRY_TO_FROMSTRING_COMPARE_EX(element_name, element_value) \
    __N_ENUM_MACRO_ENTRY_COMPARE_EX(element_name)                                  \
    return element_name;
#define __N_ENUM_MACRO_ENTRY_TO_ISSTRINGVALID_COMPARE(element_name, element_value) \
    __N_ENUM_MACRO_ENTRY_COMPARE(element_name)                                     \
    return true;
/* MACROS FOR N_ENUMS MACRO ENTRIES (END) */

/* MACRO FOR ENUM DECLARATION (START) */
#define __N_ENUM_DECLARE_ENUM(MACRO_DEFINITION, enum_name)     \
    typedef enum enum_name {                                   \
        MACRO_DEFINITION(__N_ENUM_MACRO_ENTRY_TO_ENUM_ELEMENT) \
            __N_ENUM_MACRO_ENTRY_UNKNOWN_VALUE(enum_name)      \
    } enum_name;
/* MACRO FOR ENUM DECLARATION (END) */

/* MACRO FOR N_ENUMS FUNCTIONS * PREFIX : __N_ENUM_FUNCTION_ */
#define __N_ENUM_DECLARE_FUNCTION(__N_ENUM_FUNCTION, enum_name) __N_ENUM_FUNCTION(enum_name);  // MACRO for function declaration (just add ; after function)
#define __N_ENUM_FUNCTION_ISVALID(enum_name) \
    bool N_ENUM_ENTRY(enum_name, isValid)(enum_name value)
#define __N_ENUM_FUNCTION_TOSTRING(enum_name) \
    const char* N_ENUM_ENTRY(enum_name, toString)(enum_name value)
#define __N_ENUM_FUNCTION_ISSTRINGVALID(enum_name) \
    bool N_ENUM_ENTRY(enum_name, isStringValid)(const char* str_value)
#define __N_ENUM_FUNCTION_FROMSTRING(enum_name) \
    enum_name N_ENUM_ENTRY(enum_name, fromString)(const char* str_value)
#define __N_ENUM_FUNCTION_FROMSTRING_EX(enum_name) \
    enum_name N_ENUM_ENTRY(enum_name, fromStringEx)(const char* str_value, int index)
/* MACRO FOR N_ENUMS FUNCTIONS (END) */

/* MACRO FOR N_ENUMS FUNCTIONS DEFINITIONS * PREFIX : __N_ENUM_DEFINE_FUNCTION_ */
#define __N_ENUM_DEFINE_FUNCTION_ISVALID(MACRO_DEFINITION, enum_name) \
    __N_ENUM_FUNCTION_ISVALID(enum_name) {                            \
        switch (value) {                                              \
            MACRO_DEFINITION(__N_ENUM_MACRO_ENTRY_TO_ISVALID_CASE)    \
            default:                                                  \
                return false;                                         \
        }                                                             \
    }
#define __N_ENUM_DEFINE_FUNCTION_TOSTRING(MACRO_DEFINITION, enum_name) \
    __N_ENUM_FUNCTION_TOSTRING(enum_name) {                            \
        switch (value) {                                               \
            MACRO_DEFINITION(__N_ENUM_MACRO_ENTRY_TO_TOSTRING_CASE)    \
            default:                                                   \
                return 0;                                              \
        }                                                              \
    }
#define __N_ENUM_DEFINE_FUNCTION_ISSTRINGVALID(MACRO_DEFINITION, enum_name) \
    __N_ENUM_FUNCTION_ISSTRINGVALID(enum_name) {                            \
        if (!str_value) return false;                                       \
        MACRO_DEFINITION(__N_ENUM_MACRO_ENTRY_TO_ISSTRINGVALID_COMPARE)     \
        return false;                                                       \
    }
#define __N_ENUM_DEFINE_FUNCTION_FROMSTRING(MACRO_DEFINITION, enum_name)      \
    __N_ENUM_FUNCTION_FROMSTRING(enum_name) {                                 \
        if (!str_value) return __N_ENUM_MACRO_ENTRY_UNKNOWN_VALUE(enum_name); \
        MACRO_DEFINITION(__N_ENUM_MACRO_ENTRY_TO_FROMSTRING_COMPARE)          \
        return __N_ENUM_MACRO_ENTRY_UNKNOWN_VALUE(enum_name);                 \
    }
#define __N_ENUM_DEFINE_FUNCTION_FROMSTRING_EX(MACRO_DEFINITION, enum_name)   \
    __N_ENUM_FUNCTION_FROMSTRING_EX(enum_name) {                              \
        if (!str_value) return __N_ENUM_MACRO_ENTRY_UNKNOWN_VALUE(enum_name); \
        MACRO_DEFINITION(__N_ENUM_MACRO_ENTRY_TO_FROMSTRING_COMPARE_EX)       \
        return __N_ENUM_MACRO_ENTRY_UNKNOWN_VALUE(enum_name);                 \
    }
/* MACRO FOR N_ENUMS FUNCTIONS DEFINITIONS (END) */

/* N_ENUM DECLARATION */
#define N_ENUM_DECLARE(MACRO_DEFINITION, enum_name)                       \
    __N_ENUM_DECLARE_ENUM(MACRO_DEFINITION, enum_name)                    \
    __N_ENUM_DECLARE_FUNCTION(__N_ENUM_FUNCTION_ISVALID, enum_name)       \
    __N_ENUM_DECLARE_FUNCTION(__N_ENUM_FUNCTION_ISSTRINGVALID, enum_name) \
    __N_ENUM_DECLARE_FUNCTION(__N_ENUM_FUNCTION_TOSTRING, enum_name)      \
    __N_ENUM_DECLARE_FUNCTION(__N_ENUM_FUNCTION_FROMSTRING, enum_name)    \
    __N_ENUM_DECLARE_FUNCTION(__N_ENUM_FUNCTION_FROMSTRING_EX, enum_name)
/* N_ENUM DECLARATION (END) */

/* N_ENUM DEFINITION */
#define N_ENUM_DEFINE(MACRO_DEFINITION, enum_name)                      \
    __N_ENUM_DEFINE_FUNCTION_ISVALID(MACRO_DEFINITION, enum_name)       \
    __N_ENUM_DEFINE_FUNCTION_ISSTRINGVALID(MACRO_DEFINITION, enum_name) \
    __N_ENUM_DEFINE_FUNCTION_TOSTRING(MACRO_DEFINITION, enum_name)      \
    __N_ENUM_DEFINE_FUNCTION_FROMSTRING(MACRO_DEFINITION, enum_name)    \
    __N_ENUM_DEFINE_FUNCTION_FROMSTRING_EX(MACRO_DEFINITION, enum_name)
/* N_ENUM DEFINITION (END) */


#ifdef __cplusplus
}
#endif

#endif  // header guard