port_def.inc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. /*
  2. * This is where we define macros used across upb.
  3. *
  4. * All of these macros are undef'd in port_undef.inc to avoid leaking them to
  5. * users.
  6. *
  7. * The correct usage is:
  8. *
  9. * #include "upb/foobar.h"
  10. * #include "upb/baz.h"
  11. *
  12. * // MUST be last included header.
  13. * #include "upb/port_def.inc"
  14. *
  15. * // Code for this file.
  16. * // <...>
  17. *
  18. * // Can be omitted for .c files, required for .h.
  19. * #include "upb/port_undef.inc"
  20. *
  21. * This file is private and must not be included by users!
  22. */
  23. #ifndef UINTPTR_MAX
  24. #error must include stdint.h first
  25. #endif
  26. #if UINTPTR_MAX == 0xffffffff
  27. #define UPB_SIZE(size32, size64) size32
  28. #else
  29. #define UPB_SIZE(size32, size64) size64
  30. #endif
  31. #define UPB_FIELD_AT(msg, fieldtype, offset) \
  32. *(fieldtype*)((const char*)(msg) + offset)
  33. #define UPB_READ_ONEOF(msg, fieldtype, offset, case_offset, case_val, default) \
  34. UPB_FIELD_AT(msg, int, case_offset) == case_val \
  35. ? UPB_FIELD_AT(msg, fieldtype, offset) \
  36. : default
  37. #define UPB_WRITE_ONEOF(msg, fieldtype, offset, value, case_offset, case_val) \
  38. UPB_FIELD_AT(msg, int, case_offset) = case_val; \
  39. UPB_FIELD_AT(msg, fieldtype, offset) = value;
  40. /* UPB_INLINE: inline if possible, emit standalone code if required. */
  41. #ifdef __cplusplus
  42. #define UPB_INLINE inline
  43. #elif defined (__GNUC__) || defined(__clang__)
  44. #define UPB_INLINE static __inline__
  45. #else
  46. #define UPB_INLINE static
  47. #endif
  48. /* Hints to the compiler about likely/unlikely branches. */
  49. #if defined (__GNUC__) || defined(__clang__)
  50. #define UPB_LIKELY(x) __builtin_expect((x),1)
  51. #define UPB_UNLIKELY(x) __builtin_expect((x),0)
  52. #else
  53. #define UPB_LIKELY(x) (x)
  54. #define UPB_UNLIKELY(x) (x)
  55. #endif
  56. /* Define UPB_BIG_ENDIAN manually if you're on big endian and your compiler
  57. * doesn't provide these preprocessor symbols. */
  58. #if defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
  59. #define UPB_BIG_ENDIAN
  60. #endif
  61. /* Macros for function attributes on compilers that support them. */
  62. #ifdef __GNUC__
  63. #define UPB_FORCEINLINE __inline__ __attribute__((always_inline))
  64. #define UPB_NOINLINE __attribute__((noinline))
  65. #define UPB_NORETURN __attribute__((__noreturn__))
  66. #else /* !defined(__GNUC__) */
  67. #define UPB_FORCEINLINE
  68. #define UPB_NOINLINE
  69. #define UPB_NORETURN
  70. #endif
  71. #if __STDC_VERSION__ >= 199901L || __cplusplus >= 201103L
  72. /* C99/C++11 versions. */
  73. #include <stdio.h>
  74. #define _upb_snprintf snprintf
  75. #define _upb_vsnprintf vsnprintf
  76. #define _upb_va_copy(a, b) va_copy(a, b)
  77. #elif defined(_MSC_VER)
  78. /* Microsoft C/C++ versions. */
  79. #include <stdarg.h>
  80. #include <stdio.h>
  81. #if _MSC_VER < 1900
  82. int msvc_snprintf(char* s, size_t n, const char* format, ...);
  83. int msvc_vsnprintf(char* s, size_t n, const char* format, va_list arg);
  84. #define UPB_MSVC_VSNPRINTF
  85. #define _upb_snprintf msvc_snprintf
  86. #define _upb_vsnprintf msvc_vsnprintf
  87. #else
  88. #define _upb_snprintf snprintf
  89. #define _upb_vsnprintf vsnprintf
  90. #endif
  91. #define _upb_va_copy(a, b) va_copy(a, b)
  92. #elif defined __GNUC__
  93. /* A few hacky workarounds for functions not in C89.
  94. * For internal use only!
  95. * TODO(haberman): fix these by including our own implementations, or finding
  96. * another workaround.
  97. */
  98. #define _upb_snprintf __builtin_snprintf
  99. #define _upb_vsnprintf __builtin_vsnprintf
  100. #define _upb_va_copy(a, b) __va_copy(a, b)
  101. #else
  102. #error Need implementations of [v]snprintf and va_copy
  103. #endif
  104. #ifdef __cplusplus
  105. #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || \
  106. (defined(_MSC_VER) && _MSC_VER >= 1900)
  107. /* C++11 is present */
  108. #else
  109. #error upb requires C++11 for C++ support
  110. #endif
  111. #endif
  112. #define UPB_MAX(x, y) ((x) > (y) ? (x) : (y))
  113. #define UPB_MIN(x, y) ((x) < (y) ? (x) : (y))
  114. #define UPB_UNUSED(var) (void)var
  115. /* UPB_ASSERT(): in release mode, we use the expression without letting it be
  116. * evaluated. This prevents "unused variable" warnings. */
  117. #ifdef NDEBUG
  118. #define UPB_ASSERT(expr) do {} while (false && (expr))
  119. #else
  120. #define UPB_ASSERT(expr) assert(expr)
  121. #endif
  122. /* UPB_ASSERT_DEBUGVAR(): assert that uses functions or variables that only
  123. * exist in debug mode. This turns into regular assert. */
  124. #define UPB_ASSERT_DEBUGVAR(expr) assert(expr)
  125. #if defined(__GNUC__) || defined(__clang__)
  126. #define UPB_UNREACHABLE() do { assert(0); __builtin_unreachable(); } while(0)
  127. #else
  128. #define UPB_UNREACHABLE() do { assert(0); } while(0)
  129. #endif
  130. /* UPB_INFINITY representing floating-point positive infinity. */
  131. #include <math.h>
  132. #ifdef INFINITY
  133. #define UPB_INFINITY INFINITY
  134. #else
  135. #define UPB_INFINITY (1.0 / 0.0)
  136. #endif