Commit dc8c21a9 authored by Christopher Dykes's avatar Christopher Dykes Committed by Facebook Github Bot 9

Deal with some oddities of MSVC's preprocessor

Summary: MSVC's preprocessor is different in how it deals with passing arguments expanded from `__VA_ARGS__`, so we have to add a stub to force it to expand the arguments.

Reviewed By: yfeldblum

Differential Revision: D3256328

fbshipit-source-id: 551434833d40e55498a9ab352eb74acdfd094835
parent d65a097e
...@@ -46,6 +46,10 @@ ...@@ -46,6 +46,10 @@
#define FB_THIRD(a, b, ...) __VA_ARGS__ #define FB_THIRD(a, b, ...) __VA_ARGS__
#endif #endif
// MSVC's preprocessor is a pain, so we have to
// forcefully expand the VA args in some places.
#define FB_VA_GLUE(a, b) a b
/** /**
* Helper macro that extracts the first argument out of a list of any * Helper macro that extracts the first argument out of a list of any
* number of arguments. * number of arguments.
...@@ -57,7 +61,14 @@ ...@@ -57,7 +61,14 @@
* number of arguments. If only one argument is given, it returns * number of arguments. If only one argument is given, it returns
* that. * that.
*/ */
#ifdef _MSC_VER
// GCC refuses to expand this correctly if this macro itself was
// called with FB_VA_GLUE :(
#define FB_ARG_2_OR_1(...) \
FB_VA_GLUE(FB_ARG_2_OR_1_IMPL, (__VA_ARGS__, __VA_ARGS__))
#else
#define FB_ARG_2_OR_1(...) FB_ARG_2_OR_1_IMPL(__VA_ARGS__, __VA_ARGS__) #define FB_ARG_2_OR_1(...) FB_ARG_2_OR_1_IMPL(__VA_ARGS__, __VA_ARGS__)
#endif
// Support macro for the above // Support macro for the above
#define FB_ARG_2_OR_1_IMPL(a, b, ...) b #define FB_ARG_2_OR_1_IMPL(a, b, ...) b
......
...@@ -683,37 +683,46 @@ void swap(Synchronized<T, M>& lhs, Synchronized<T, M>& rhs) { ...@@ -683,37 +683,46 @@ void swap(Synchronized<T, M>& lhs, Synchronized<T, M>& rhs) {
#define SYNCHRONIZED(...) \ #define SYNCHRONIZED(...) \
FOLLY_PUSH_WARNING \ FOLLY_PUSH_WARNING \
FOLLY_GCC_DISABLE_WARNING(shadow) \ FOLLY_GCC_DISABLE_WARNING(shadow) \
if (bool SYNCHRONIZED_state = false) {} else \ if (bool SYNCHRONIZED_state = false) { \
} else \
for (auto SYNCHRONIZED_lockedPtr = \ for (auto SYNCHRONIZED_lockedPtr = \
(FB_ARG_2_OR_1(__VA_ARGS__)).operator->(); \ (FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).operator->(); \
!SYNCHRONIZED_state; SYNCHRONIZED_state = true) \ !SYNCHRONIZED_state; \
for (auto& FB_ARG_1(__VA_ARGS__) = \ SYNCHRONIZED_state = true) \
for (auto& FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)) = \
*SYNCHRONIZED_lockedPtr.operator->(); \ *SYNCHRONIZED_lockedPtr.operator->(); \
!SYNCHRONIZED_state; SYNCHRONIZED_state = true) \ !SYNCHRONIZED_state; \
SYNCHRONIZED_state = true) \
FOLLY_POP_WARNING FOLLY_POP_WARNING
#define TIMED_SYNCHRONIZED(timeout, ...) \ #define TIMED_SYNCHRONIZED(timeout, ...) \
if (bool SYNCHRONIZED_state = false) {} else \ if (bool SYNCHRONIZED_state = false) { \
} else \
for (auto SYNCHRONIZED_lockedPtr = \ for (auto SYNCHRONIZED_lockedPtr = \
(FB_ARG_2_OR_1(__VA_ARGS__)).timedAcquire(timeout); \ (FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).timedAcquire(timeout); \
!SYNCHRONIZED_state; SYNCHRONIZED_state = true) \ !SYNCHRONIZED_state; \
for (auto FB_ARG_1(__VA_ARGS__) = \ SYNCHRONIZED_state = true) \
for (auto FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)) = \
SYNCHRONIZED_lockedPtr.operator->(); \ SYNCHRONIZED_lockedPtr.operator->(); \
!SYNCHRONIZED_state; SYNCHRONIZED_state = true) !SYNCHRONIZED_state; \
SYNCHRONIZED_state = true)
/** /**
* Similar to SYNCHRONIZED, but only uses a read lock. * Similar to SYNCHRONIZED, but only uses a read lock.
*/ */
#define SYNCHRONIZED_CONST(...) \ #define SYNCHRONIZED_CONST(...) \
SYNCHRONIZED(FB_ARG_1(__VA_ARGS__), \ SYNCHRONIZED( \
(FB_ARG_2_OR_1(__VA_ARGS__)).asConst()) FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)), \
(FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).asConst())
/** /**
* Similar to TIMED_SYNCHRONIZED, but only uses a read lock. * Similar to TIMED_SYNCHRONIZED, but only uses a read lock.
*/ */
#define TIMED_SYNCHRONIZED_CONST(timeout, ...) \ #define TIMED_SYNCHRONIZED_CONST(timeout, ...) \
TIMED_SYNCHRONIZED(timeout, FB_ARG_1(__VA_ARGS__), \ TIMED_SYNCHRONIZED( \
(FB_ARG_2_OR_1(__VA_ARGS__)).asConst()) timeout, \
FB_VA_GLUE(FB_ARG_1, (__VA_ARGS__)), \
(FB_VA_GLUE(FB_ARG_2_OR_1, (__VA_ARGS__))).asConst())
/** /**
* Temporarily disables synchronization inside a SYNCHRONIZED block. * Temporarily disables synchronization inside a SYNCHRONIZED block.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment