Increase the priority of the ALSA backend
[openal-soft.git] / common / opthelpers.h
blobe46c0f3a9bfb83494f281801493142de12307e30
1 #ifndef OPTHELPERS_H
2 #define OPTHELPERS_H
4 #include <cstdint>
5 #include <utility>
8 #ifdef __has_builtin
9 #define HAS_BUILTIN __has_builtin
10 #else
11 #define HAS_BUILTIN(x) (0)
12 #endif
14 #ifdef __GNUC__
15 #define force_inline [[gnu::always_inline]]
16 #elif defined(_MSC_VER)
17 #define force_inline __forceinline
18 #else
19 #define force_inline inline
20 #endif
22 #if defined(__GNUC__) || HAS_BUILTIN(__builtin_expect)
23 /* likely() optimizes for the case where the condition is true. The condition
24 * is not required to be true, but it can result in more optimal code for the
25 * true path at the expense of a less optimal false path.
27 template<typename T>
28 force_inline constexpr bool likely(T&& expr) noexcept
29 { return __builtin_expect(static_cast<bool>(std::forward<T>(expr)), true); }
30 /* The opposite of likely(), optimizing for the case where the condition is
31 * false.
33 template<typename T>
34 force_inline constexpr bool unlikely(T&& expr) noexcept
35 { return __builtin_expect(static_cast<bool>(std::forward<T>(expr)), false); }
37 #else
39 template<typename T>
40 force_inline constexpr bool likely(T&& expr) noexcept
41 { return static_cast<bool>(std::forward<T>(expr)); }
42 template<typename T>
43 force_inline constexpr bool unlikely(T&& expr) noexcept
44 { return static_cast<bool>(std::forward<T>(expr)); }
45 #endif
46 #define LIKELY(x) (likely(x))
47 #define UNLIKELY(x) (unlikely(x))
49 #if HAS_BUILTIN(__builtin_assume)
50 /* Unlike LIKELY, ASSUME requires the condition to be true or else it invokes
51 * undefined behavior. It's essentially an assert without actually checking the
52 * condition at run-time, allowing for stronger optimizations than LIKELY.
54 #define ASSUME __builtin_assume
55 #elif defined(_MSC_VER)
56 #define ASSUME __assume
57 #elif defined(__GNUC__)
58 #define ASSUME(x) do { if(x) break; __builtin_unreachable(); } while(0)
59 #else
60 #define ASSUME(x) ((void)0)
61 #endif
63 namespace al {
65 template<std::size_t alignment, typename T>
66 force_inline constexpr auto assume_aligned(T *ptr) noexcept
68 #ifdef __cpp_lib_assume_aligned
69 return std::assume_aligned<alignment,T>(ptr);
70 #elif defined(__clang__) || (defined(__GNUC__) && !defined(__ICC))
71 return static_cast<T*>(__builtin_assume_aligned(ptr, alignment));
72 #elif defined(_MSC_VER)
73 constexpr std::size_t alignment_mask{(1<<alignment) - 1};
74 if((reinterpret_cast<std::uintptr_t>(ptr)&alignment_mask) == 0)
75 return ptr;
76 __assume(0);
77 #elif defined(__ICC)
78 __assume_aligned(ptr, alignment);
79 return ptr;
80 #else
81 return ptr;
82 #endif
85 } // namespace al
87 #endif /* OPTHELPERS_H */