Skip to main content
added 549 characters in body
Source Link
Madagascar
  • 10.2k
  • 1
  • 16
  • 52

Edit: The code was compiled with Clang 18.1 on a Linux Mint 21.2 x86_64 virtual machine with the following compiler flags:

clang-18 -std=c2x -g3 -ggdb -no-pie -Wall -Wextra -Warray-bounds -Wconversion -Wformat-signedness -Wmissing-braces -Wno-parentheses -Wpedantic -Wstrict-prototypes -Wwrite-strings -Winline -s -fno-builtin -fno-common -fno-omit-frame-pointer -fsanitize=float-cast-overflow -fsanitize=address -fsanitize=undefined -fsanitize=leak    max_test.c   -o max_test

It emitted no warnings, except that Wformat-signedness is an unknown warning option.


Edit: The code was compiled with Clang 18.1 on a Linux Mint 21.2 x86_64 virtual machine with the following compiler flags:

clang-18 -std=c2x -g3 -ggdb -no-pie -Wall -Wextra -Warray-bounds -Wconversion -Wformat-signedness -Wmissing-braces -Wno-parentheses -Wpedantic -Wstrict-prototypes -Wwrite-strings -Winline -s -fno-builtin -fno-common -fno-omit-frame-pointer -fsanitize=float-cast-overflow -fsanitize=address -fsanitize=undefined -fsanitize=leak    max_test.c   -o max_test

It emitted no warnings, except that Wformat-signedness is an unknown warning option.

edited tags
Link
Madagascar
  • 10.2k
  • 1
  • 16
  • 52
added 85 characters in body
Source Link
Madagascar
  • 10.2k
  • 1
  • 16
  • 52
#ifndef MIN_H
#define MIN_H 1

#include <limits.h>

#include "max.h"

/* Current versions of gcc and clang support -std=c2x which sets 
 * __STDC_VERSION__ to this placeholder value. GCC 14.1 does not set
 * __STDC_VERSION__ to 202311L with the std=c23 flag, but Clang 18.1 does. */
#define C23_PLACEHOLDER 202000L
    
#if defined(__STDC_VERSION__) && __STDC_VERSION >= C23_PLACEHOLDER
    /* gnu::const is stricter than unsequenced, but it doesn't matter here. */
    #define ATTRIB_CONST            [[unsequenced]]
#elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER)
    #define ATTRIB_CONST            __attribute__((const))
#else
    #define ATTRIB_CONST            /**/
#endif

#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER)
    #define ATTRIB_ALWAYS_INLINE    __attribute__((always_inline))
#else
    #define ATTRIB_ALWAYS_INLINE    /**/
#endif

#define gen_basic_min(return_type, param_type1, param_type2, suffix)   \
    ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline return_type min_##suffix(param_type1 a, param_type2 b) \
    { return a < b ? (return_type) a : (return_type) b; }

#define gen_nonbasic_min(return_type, param_type1, param_type2, cast_type, suffix) \
    ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline return_type min_##suffix(param_type1 a, param_type2 b) \
    { return max_##suffix(a, b) == a ? b : (cast_type) a; }

gen_basic_min(int, int, int, i_i)
gen_basic_min(long, int, long, i_li)
gen_basic_min(long long, int, long long, i_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_ui(int a, unsigned b)
{
    return max_i_ui(a, b) == b ? a : (int) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_uli(int a, unsigned long b)
{
    return max_i_uli(a, b) == b ? a : (int) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_ulli(int a, unsigned long long b)
{
    return max_i_ulli(a, b) == b ? a : (int) b;
}

#define MIN_I(a, b)     _Generic((b),                                   \
                            int:                    min_i_i,            \
                            unsigned int:           min_i_ui,           \
                            long int:               min_i_li,           \
                            unsigned long int:      min_i_uli,          \
                            long long int:          min_i_lli,          \
                            unsigned long long int: min_i_ulli)((a), (b))

gen_basic_min(unsigned, unsigned, unsigned, ui_ui)
gen_basic_min(unsigned, unsigned, unsigned long, ui_uli)
gen_basic_min(unsigned, unsigned, unsigned long long, ui_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_ui_i(unsigned a, int b)
{
    return min_i_ui(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_ui_li(unsigned a, long b)
{
    #if LONG_MAX >= UINT_MAX
    return max_ui_li(a, b) == b ? (long) a : b;
    #else
    return max_ui_li(a, b) == a ? b : (long) a;
    #endif
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_ui_lli(unsigned a, long long b)
{
    #if LLONG_MAX >= UINT_MAX
    return max_ui_lli(a, b) == b ? (long long) a : b;
    #else
    return max_ui_lli(a, b) == a ? b : (long long) a;
    #endif
}

#define MIN_UI(a, b)     _Generic((b),                                  \
                            int:                    min_ui_i,           \
                            unsigned int:           min_ui_ui,          \
                            long int:               min_ui_li,          \
                            unsigned long int:      min_ui_uli,         \
                            long long int:          min_ui_lli,         \
                            unsigned long long int: min_ui_ulli)((a), (b))

gen_basic_min(long, long, int, li_i)
gen_basic_min(long, long, long, li_li)
gen_basic_min(long long, long, long long, li_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_ui(long a, unsigned b)
{
    return min_ui_li(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_uli(long a, unsigned long b)
{
    return max_li_uli(a, b) == b ? a : (long) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_ulli(long a, unsigned long long b)
{
    return max_li_ulli(a, b) == b ? a : (long) b;
}

#define MIN_LI(a, b)    _Generic((b),                                   \
                            int:                    min_li_i,           \
                            unsigned int:           min_li_ui,          \
                            long int:               min_li_li,          \
                            unsigned long int:      min_li_uli,         \
                            long long int:          min_li_lli,         \
                            unsigned long long int: min_li_ulli)((a), (b))

gen_basic_min(unsigned, unsigned long, unsigned, uli_ui)
gen_basic_min(unsigned long, unsigned long, unsigned long, uli_uli)
gen_basic_min(unsigned long, unsigned long, unsigned long long, uli_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_uli_i(unsigned long a, int b)
{
    return min_i_uli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_uli_li(unsigned long a, long b)
{
    return min_li_uli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_uli_lli(unsigned long a, long long b)
{
    #if LLONG_MAX >= ULONG_MAX
    return max_uli_lli(a, b) == b ? (long long) a : b;
    #else
    return max_uli_lli(a, b) == a ? b : (long long) a;
    #endif
}

#define MIN_ULI(a, b)   _Generic((b),                                   \
                            int:                    min_uli_i,          \
                            unsigned int:           min_uli_ui,         \
                            long int:               min_uli_li,         \
                            unsigned long int:      min_uli_uli,        \
                            long long int:          min_uli_lli,        \
                            unsigned long long int: min_uli_ulli)((a), (b))

gen_basic_min(long long, long long, int, lli_i)
gen_basic_min(long long, long long, long, lli_li)
gen_basic_min(long long, long long, long long, lli_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_ui(long long a, unsigned b)
{
    return min_ui_lli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_uli(long long a, unsigned long b)
{
    return min_uli_lli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_ulli(long long a, unsigned long long b)
{
    return max_lli_ulli(a, b) == b ? a : (long long) b;
}

#define MIN_LLI(a, b)   _Generic((b),                                   \
                            int:                    min_lli_i,          \
                            unsigned int:           min_lli_ui,         \
                            long int:               min_lli_li,         \
                            unsigned long int:      min_lli_uli,        \
                            long long int:          min_lli_lli,        \
                            unsigned long long int: min_lli_ulli)((a), (b))

gen_basic_min(unsigned, unsigned long long, unsigned, ulli_ui)
gen_basic_min(unsigned long, unsigned long long, unsigned long, ulli_uli)
gen_basic_min(unsigned long long, unsigned long long, unsigned long long, ulli_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_ulli_i(unsigned long long a, int b)
{
    return min_i_ulli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_ulli_li(unsigned long long a, long b)
{
    return min_li_ulli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_ulli_lli(unsigned long long a, long long b)
{
    return min_lli_ulli(b, a);
}

/* gen_nonbasic_min(int, unsigned long long, int, int, ulli_i) */
/* gen_nonbasic_min(long, unsigned long long, long, long, ulli_li) */
/* gen_nonbasic_min(long long, unsigned long long, long long, long, ulli_lli) */

#define MIN_ULLI(a, b)  _Generic((b),                                   \
                            int:                    min_ulli_i,         \
                            unsigned int:           min_ulli_ui,        \
                            long int:               min_ulli_li,        \
                            unsigned long int:      min_ulli_uli,       \
                            long long int:          min_ulli_lli,       \
                            unsigned long long int: min_ulli_ulli)((a), (b))

#define MIN(a, b)       _Generic((a) + 0,                                       \
                            int:                    MIN_I((a) + 0, (b) + 0),    \
                            unsigned int:           MIN_UI((a) + 0, (b) + 0),   \
                            long int:               MIN_LI((a) + 0, (b) + 0),   \
                            unsigned long int:      MIN_ULI((a) + 0, (b) + 0),  \
                            long long int:          MIN_LLI((a) + 0, (b) + 0),  \
                            unsigned long long int: MIN_ULLI((a) + 0, (b) + 0))

#undef ATTRIB_ALWAYS_INLINE
#undef ATTRIB_CONST
#undef C23_PLACEHOLDER

#endif  /* MIN_H */
#ifndef MIN_H
#define MIN_H 1

#include <limits.h>

#include "max.h"

/* Current versions of gcc and clang support -std=c2x which sets 
 * __STDC_VERSION__ to this placeholder value. GCC 14.1 does not set
 * __STDC_VERSION__ to 202311L with the std=c23 flag, but Clang 18.1 does. */
#define C23_PLACEHOLDER 202000L
    
#if defined(__STDC_VERSION__) && __STDC_VERSION >= C23_PLACEHOLDER
    /* gnu::const is stricter than unsequenced, but it doesn't matter here. */
    #define ATTRIB_CONST            [[unsequenced]]
#elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER)
    #define ATTRIB_CONST            __attribute__((const))
#else
    #define ATTRIB_CONST            /**/
#endif

#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER)
    #define ATTRIB_ALWAYS_INLINE    __attribute__((always_inline))
#else
    #define ATTRIB_ALWAYS_INLINE    /**/
#endif

#define gen_basic_min(return_type, param_type1, param_type2, suffix)   \
    ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline return_type min_##suffix(param_type1 a, param_type2 b) \
    { return a < b ? (return_type) a : (return_type) b; }

#define gen_nonbasic_min(return_type, param_type1, param_type2, cast_type, suffix) \
    ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline return_type min_##suffix(param_type1 a, param_type2 b) \
    { return max_##suffix(a, b) == a ? b : (cast_type) a; }

gen_basic_min(int, int, int, i_i)
gen_basic_min(long, int, long, i_li)
gen_basic_min(long long, int, long long, i_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_ui(int a, unsigned b)
{
    return max_i_ui(a, b) == b ? a : (int) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_uli(int a, unsigned long b)
{
    return max_i_uli(a, b) == b ? a : (int) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_ulli(int a, unsigned long long b)
{
    return max_i_ulli(a, b) == b ? a : (int) b;
}

#define MIN_I(a, b)     _Generic((b),                                   \
                            int:                    min_i_i,            \
                            unsigned int:           min_i_ui,           \
                            long int:               min_i_li,           \
                            unsigned long int:      min_i_uli,          \
                            long long int:          min_i_lli,          \
                            unsigned long long int: min_i_ulli)((a), (b))

gen_basic_min(unsigned, unsigned, unsigned, ui_ui)
gen_basic_min(unsigned, unsigned, unsigned long, ui_uli)
gen_basic_min(unsigned, unsigned, unsigned long long, ui_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_ui_i(unsigned a, int b)
{
    return min_i_ui(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_ui_li(unsigned a, long b)
{
    #if LONG_MAX >= UINT_MAX
    return max_ui_li(a, b) == b ? (long) a : b;
    #else
    return max_ui_li(a, b) == a ? b : (long) a;
    #endif
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_ui_lli(unsigned a, long long b)
{
    #if LLONG_MAX >= UINT_MAX
    return max_ui_lli(a, b) == b ? (long long) a : b;
    #else
    return max_ui_lli(a, b) == a ? b : (long long) a;
    #endif
}

#define MIN_UI(a, b)     _Generic((b),                                  \
                            int:                    min_ui_i,           \
                            unsigned int:           min_ui_ui,          \
                            long int:               min_ui_li,          \
                            unsigned long int:      min_ui_uli,         \
                            long long int:          min_ui_lli,         \
                            unsigned long long int: min_ui_ulli)((a), (b))

gen_basic_min(long, long, int, li_i)
gen_basic_min(long, long, long, li_li)
gen_basic_min(long long, long, long long, li_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_ui(long a, unsigned b)
{
    return min_ui_li(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_uli(long a, unsigned long b)
{
    return max_li_uli(a, b) == b ? a : (long) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_ulli(long a, unsigned long long b)
{
    return max_li_ulli(a, b) == b ? a : (long) b;
}

#define MIN_LI(a, b)    _Generic((b),                                   \
                            int:                    min_li_i,           \
                            unsigned int:           min_li_ui,          \
                            long int:               min_li_li,          \
                            unsigned long int:      min_li_uli,         \
                            long long int:          min_li_lli,         \
                            unsigned long long int: min_li_ulli)((a), (b))

gen_basic_min(unsigned, unsigned long, unsigned, uli_ui)
gen_basic_min(unsigned long, unsigned long, unsigned long, uli_uli)
gen_basic_min(unsigned long, unsigned long, unsigned long long, uli_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_uli_i(unsigned long a, int b)
{
    return min_i_uli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_uli_li(unsigned long a, long b)
{
    return min_li_uli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_uli_lli(unsigned long a, long long b)
{
    #if LLONG_MAX >= ULONG_MAX
    return max_uli_lli(a, b) == b ? (long long) a : b;
    #else
    return max_uli_lli(a, b) == a ? b : (long long) a;
    #endif
}

#define MIN_ULI(a, b)   _Generic((b),                                   \
                            int:                    min_uli_i,          \
                            unsigned int:           min_uli_ui,         \
                            long int:               min_uli_li,         \
                            unsigned long int:      min_uli_uli,        \
                            long long int:          min_uli_lli,        \
                            unsigned long long int: min_uli_ulli)((a), (b))

gen_basic_min(long long, long long, int, lli_i)
gen_basic_min(long long, long long, long, lli_li)
gen_basic_min(long long, long long, long long, lli_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_ui(long long a, unsigned b)
{
    return min_ui_lli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_uli(long long a, unsigned long b)
{
    return min_uli_lli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_ulli(long long a, unsigned long long b)
{
    return max_lli_ulli(a, b) == b ? a : (long long) b;
}

#define MIN_LLI(a, b)   _Generic((b),                                   \
                            int:                    min_lli_i,          \
                            unsigned int:           min_lli_ui,         \
                            long int:               min_lli_li,         \
                            unsigned long int:      min_lli_uli,        \
                            long long int:          min_lli_lli,        \
                            unsigned long long int: min_lli_ulli)((a), (b))

gen_basic_min(unsigned, unsigned long long, unsigned, ulli_ui)
gen_basic_min(unsigned long, unsigned long long, unsigned long, ulli_uli)
gen_basic_min(unsigned long long, unsigned long long, unsigned long long, ulli_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_ulli_i(unsigned long long a, int b)
{
    return min_i_ulli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_ulli_li(unsigned long long a, long b)
{
    return min_li_ulli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_ulli_lli(unsigned long long a, long long b)
{
    return min_lli_ulli(b, a);
}

/* gen_nonbasic_min(int, unsigned long long, int, int, ulli_i) */
/* gen_nonbasic_min(long, unsigned long long, long, long, ulli_li) */
/* gen_nonbasic_min(long long, unsigned long long, long long, long, ulli_lli) */

#define MIN_ULLI(a, b)  _Generic((b),                                   \
                            int:                    min_ulli_i,         \
                            unsigned int:           min_ulli_ui,        \
                            long int:               min_ulli_li,        \
                            unsigned long int:      min_ulli_uli,       \
                            long long int:          min_ulli_lli,       \
                            unsigned long long int: min_ulli_ulli)((a), (b))

#define MIN(a, b)       _Generic((a) + 0,                                       \
                            int:                    MIN_I((a) + 0, (b) + 0),    \
                            unsigned int:           MIN_UI((a) + 0, (b) + 0),   \
                            long int:               MIN_LI((a) + 0, (b) + 0),   \
                            unsigned long int:      MIN_ULI((a) + 0, (b) + 0),  \
                            long long int:          MIN_LLI((a) + 0, (b) + 0),  \
                            unsigned long long int: MIN_ULLI((a) + 0, (b) + 0))

#undef ATTRIB_ALWAYS_INLINE
#undef ATTRIB_CONST
#undef C23_PLACEHOLDER

#endif  /* MIN_H */
#ifndef MIN_H
#define MIN_H 1

#include <limits.h>

#include "max.h"

/* Current versions of gcc and clang support -std=c2x which sets 
 * __STDC_VERSION__ to this placeholder value. GCC 14.1 does not set
 * __STDC_VERSION__ to 202311L with the std=c23 flag, but Clang 18.1 does. */
#define C23_PLACEHOLDER 202000L
    
#if defined(__STDC_VERSION__) && __STDC_VERSION >= C23_PLACEHOLDER
    /* gnu::const is stricter than unsequenced, but it doesn't matter here. */
    #define ATTRIB_CONST            [[unsequenced]]
#elif defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER)
    #define ATTRIB_CONST            __attribute__((const))
#else
    #define ATTRIB_CONST            /**/
#endif

#if defined(__GNUC__) || defined(__clang__) || defined(__INTEL_LLVM_COMPILER)
    #define ATTRIB_ALWAYS_INLINE    __attribute__((always_inline))
#else
    #define ATTRIB_ALWAYS_INLINE    /**/
#endif

#define gen_basic_min(return_type, param_type1, param_type2, suffix)   \
    ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline return_type min_##suffix(param_type1 a, param_type2 b) \
    { return a < b ? (return_type) a : (return_type) b; }

#define gen_nonbasic_min(return_type, param_type1, param_type2, cast_type, suffix) \
    ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline return_type min_##suffix(param_type1 a, param_type2 b) \
    { return max_##suffix(a, b) == a ? b : (cast_type) a; }

gen_basic_min(int, int, int, i_i)
gen_basic_min(long, int, long, i_li)
gen_basic_min(long long, int, long long, i_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_ui(int a, unsigned b)
{
    return max_i_ui(a, b) == b ? a : (int) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_uli(int a, unsigned long b)
{
    return max_i_uli(a, b) == b ? a : (int) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_i_ulli(int a, unsigned long long b)
{
    return max_i_ulli(a, b) == b ? a : (int) b;
}

#define MIN_I(a, b)     _Generic((b),                                   \
                            int:                    min_i_i,            \
                            unsigned int:           min_i_ui,           \
                            long int:               min_i_li,           \
                            unsigned long int:      min_i_uli,          \
                            long long int:          min_i_lli,          \
                            unsigned long long int: min_i_ulli)((a), (b))

gen_basic_min(unsigned, unsigned, unsigned, ui_ui)
gen_basic_min(unsigned, unsigned, unsigned long, ui_uli)
gen_basic_min(unsigned, unsigned, unsigned long long, ui_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_ui_i(unsigned a, int b)
{
    return min_i_ui(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_ui_li(unsigned a, long b)
{
    #if LONG_MAX >= UINT_MAX
    return max_ui_li(a, b) == b ? (long) a : b;
    #else
    return max_ui_li(a, b) == a ? b : (long) a;
    #endif
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_ui_lli(unsigned a, long long b)
{
    #if LLONG_MAX >= UINT_MAX
    return max_ui_lli(a, b) == b ? (long long) a : b;
    #else
    return max_ui_lli(a, b) == a ? b : (long long) a;
    #endif
}

#define MIN_UI(a, b)     _Generic((b),                                  \
                            int:                    min_ui_i,           \
                            unsigned int:           min_ui_ui,          \
                            long int:               min_ui_li,          \
                            unsigned long int:      min_ui_uli,         \
                            long long int:          min_ui_lli,         \
                            unsigned long long int: min_ui_ulli)((a), (b))

gen_basic_min(long, long, int, li_i)
gen_basic_min(long, long, long, li_li)
gen_basic_min(long long, long, long long, li_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_ui(long a, unsigned b)
{
    return min_ui_li(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_uli(long a, unsigned long b)
{
    return max_li_uli(a, b) == b ? a : (long) b;
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_li_ulli(long a, unsigned long long b)
{
    return max_li_ulli(a, b) == b ? a : (long) b;
}

#define MIN_LI(a, b)    _Generic((b),                                   \
                            int:                    min_li_i,           \
                            unsigned int:           min_li_ui,          \
                            long int:               min_li_li,          \
                            unsigned long int:      min_li_uli,         \
                            long long int:          min_li_lli,         \
                            unsigned long long int: min_li_ulli)((a), (b))

gen_basic_min(unsigned, unsigned long, unsigned, uli_ui)
gen_basic_min(unsigned long, unsigned long, unsigned long, uli_uli)
gen_basic_min(unsigned long, unsigned long, unsigned long long, uli_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_uli_i(unsigned long a, int b)
{
    return min_i_uli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_uli_li(unsigned long a, long b)
{
    return min_li_uli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_uli_lli(unsigned long a, long long b)
{
    #if LLONG_MAX >= ULONG_MAX
    return max_uli_lli(a, b) == b ? (long long) a : b;
    #else
    return max_uli_lli(a, b) == a ? b : (long long) a;
    #endif
}

#define MIN_ULI(a, b)   _Generic((b),                                   \
                            int:                    min_uli_i,          \
                            unsigned int:           min_uli_ui,         \
                            long int:               min_uli_li,         \
                            unsigned long int:      min_uli_uli,        \
                            long long int:          min_uli_lli,        \
                            unsigned long long int: min_uli_ulli)((a), (b))

gen_basic_min(long long, long long, int, lli_i)
gen_basic_min(long long, long long, long, lli_li)
gen_basic_min(long long, long long, long long, lli_lli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_ui(long long a, unsigned b)
{
    return min_ui_lli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_uli(long long a, unsigned long b)
{
    return min_uli_lli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_lli_ulli(long long a, unsigned long long b)
{
    return max_lli_ulli(a, b) == b ? a : (long long) b;
}

#define MIN_LLI(a, b)   _Generic((b),                                   \
                            int:                    min_lli_i,          \
                            unsigned int:           min_lli_ui,         \
                            long int:               min_lli_li,         \
                            unsigned long int:      min_lli_uli,        \
                            long long int:          min_lli_lli,        \
                            unsigned long long int: min_lli_ulli)((a), (b))

gen_basic_min(unsigned, unsigned long long, unsigned, ulli_ui)
gen_basic_min(unsigned long, unsigned long long, unsigned long, ulli_uli)
gen_basic_min(unsigned long long, unsigned long long, unsigned long long, ulli_ulli)

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline int min_ulli_i(unsigned long long a, int b)
{
    return min_i_ulli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long min_ulli_li(unsigned long long a, long b)
{
    return min_li_ulli(b, a);
}

ATTRIB_ALWAYS_INLINE ATTRIB_CONST static inline long long min_ulli_lli(unsigned long long a, long long b)
{
    return min_lli_ulli(b, a);
}

#define MIN_ULLI(a, b)  _Generic((b),                                   \
                            int:                    min_ulli_i,         \
                            unsigned int:           min_ulli_ui,        \
                            long int:               min_ulli_li,        \
                            unsigned long int:      min_ulli_uli,       \
                            long long int:          min_ulli_lli,       \
                            unsigned long long int: min_ulli_ulli)((a), (b))

#define MIN(a, b)       _Generic((a) + 0,                                       \
                            int:                    MIN_I((a) + 0, (b) + 0),    \
                            unsigned int:           MIN_UI((a) + 0, (b) + 0),   \
                            long int:               MIN_LI((a) + 0, (b) + 0),   \
                            unsigned long int:      MIN_ULI((a) + 0, (b) + 0),  \
                            long long int:          MIN_LLI((a) + 0, (b) + 0),  \
                            unsigned long long int: MIN_ULLI((a) + 0, (b) + 0))

#undef ATTRIB_ALWAYS_INLINE
#undef ATTRIB_CONST
#undef C23_PLACEHOLDER

#endif  /* MIN_H */
added 85 characters in body
Source Link
Madagascar
  • 10.2k
  • 1
  • 16
  • 52
Loading
Source Link
Madagascar
  • 10.2k
  • 1
  • 16
  • 52
Loading