Implement the NS_ENUM AND NS_OPTIONS macros to (hopefully) work both on gcc

and clang.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@39029 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
thebeing 2015-10-05 18:43:44 +00:00
parent ecd7eb7c1a
commit 10f496447b
3 changed files with 50 additions and 8 deletions

View file

@ -1,3 +1,10 @@
2015-10-05 Niels Grewe <niels.grewe@halbordnung.de>
* Headers/GNUstepBase/GNUstep.h: Define __has_extension() if the
compiler does not support it.
* Headers/Foundation/NSObjCRuntime.h: Provide definitions for
NS_ENUM and NS_OPTIONS.
2015-10-03 Fred Kiefer <fredkiefer@gmx.de>
* Source/NSPropertyList.m (GSBinaryPLGenerator-storeCount:): Use

View file

@ -37,6 +37,7 @@
#import <GNUstepBase/GSVersionMacros.h>
#import <GNUstepBase/GSConfig.h>
#import <GNUstepBase/GNUstep.h>
#import <GNUstepBase/GSBlocks.h>
#include <stdarg.h>
@ -124,7 +125,34 @@ typedef float CGFloat;
extern "C" {
#endif
enum
/*
* We can have strongly typed enums in C++11 mode or when the objc_fixed_enum
* feature is availble.
*/
#if (__has_feature(objc_fixed_enum) || (__cplusplus && (__cplusplus > 199711L) && __has_extension(cxx_strong_enums)))
# define _GS_NAMED_ENUM(ty, name) enum name : ty name; enum name : ty
# define _GS_ANON_ENUM(ty) enum : ty
# if __cplusplus
# define NS_OPTIONS(ty,name) ty name; enum : ty
# else
# define NS_OPTIONS(ty,name) NS_ENUM(ty,name)
# endif
#else // this provides less information, but works with older compilers
# define _GS_NAMED_ENUM(ty, name) ty name; enum
# define _GS_ANON_ENUM(ty) enum
# define NS_OPTIONS(ty, name) NS_ENUM(ty, name)
#endif
// A bit of fairy dust to expand NS_ENUM to the correct variant
#define _GS_GET_ENUM_MACRO(_first,_second,NAME,...) NAME
/* The trick here is that placing the variadic args first will push the name
* that the _GS_GET_ENUM_MACRO expands to into the correct position.
*/
#define NS_ENUM(...) _GS_GET_ENUM_MACRO(__VA_ARGS__,_GS_NAMED_ENUM,_GS_ANON_ENUM)(__VA_ARGS__)
/** Bitfield used to specify options to control enumeration over collections.
*/
typedef NS_OPTIONS(NSUInteger, NSEnumerationOptions)
{
NSEnumerationConcurrent = (1UL << 0), /** Specifies that the enumeration
* is concurrency-safe. Note that this does not mean that it will be
@ -136,11 +164,10 @@ enum
*/
};
/** Bitfield used to specify options to control enumeration over collections.
*/
typedef NSUInteger NSEnumerationOptions;
enum
/** Bitfield used to specify options to control the sorting of collections.
*/
typedef NS_OPTIONS(NSUInteger, NSSortOptions)
{
NSSortConcurrent = (1UL << 0), /** Specifies that the sort
* is concurrency-safe. Note that this does not mean that it will be
@ -151,9 +178,6 @@ enum
*/
};
/** Bitfield used to specify options to control the sorting of collections.
*/
typedef NSUInteger NSSortOptions;
#import <GNUstepBase/GSObjCRuntime.h>

View file

@ -33,6 +33,17 @@
# define __has_feature(x) 0
#endif
/*
* __has_extension has slightly different semantics from __has_feature.
* It evaluates to true if the feature is supported by by clang for the
* current compilation unit (language and -f switches), regardless of
* whether it is part of the language standard or just a (non-standard)
* extension.
*/
#ifndef __has_extension
# define __has_extension(x) __has_feature(x)
#endif
#if GS_WITH_GC || __has_feature(objc_arc)
#ifndef RETAIN