aboutsummaryrefslogtreecommitdiffstats
path: root/common/almalloc.h
diff options
context:
space:
mode:
Diffstat (limited to 'common/almalloc.h')
-rw-r--r--common/almalloc.h37
1 files changed, 35 insertions, 2 deletions
diff --git a/common/almalloc.h b/common/almalloc.h
index 1e43acca..5efa4f63 100644
--- a/common/almalloc.h
+++ b/common/almalloc.h
@@ -101,8 +101,41 @@ constexpr bool operator==(const allocator<T,N>&, const allocator<U,M>&) noexcept
template<typename T, std::size_t N, typename U, std::size_t M>
constexpr bool operator!=(const allocator<T,N>&, const allocator<U,M>&) noexcept { return false; }
-template<size_t alignment, typename T>
-[[gnu::assume_aligned(alignment)]] constexpr T* assume_aligned(T *ptr) noexcept { return ptr; }
+#ifdef __cpp_lib_assume_aligned
+template<std::size_t alignment, typename T>
+using assume_aligned = std::assume_aligned<alignment,T>;
+
+#elif defined(__clang__) || (defined(__GNUC__) && !defined(__ICC))
+
+template<std::size_t alignment, typename T>
+[[gnu::always_inline/*,nodiscard*/]] constexpr T* assume_aligned(T *ptr) noexcept
+{ return static_cast<T*>(__builtin_assume_aligned(ptr, alignment)); }
+
+#elif defined(_MSC_VER)
+
+template<std::size_t alignment, typename T>
+__forceinline /*[[nodiscard]]*/ constexpr T* assume_aligned(T *ptr) noexcept
+{
+ static constexpr std::size_t alignment_mask{(1<<alignment) - 1};
+ if((reinterpret_cast<std::uintptr_t>(ptr)&alignment_mask) == 0)
+ return ptr;
+ __assume(0);
+}
+
+#elif defined(__ICC)
+
+template<std::size_t alignment, typename T>
+/*[[nodiscard]]*/ constexpr T* assume_aligned(T *ptr) noexcept
+{
+ __assume_aligned(ptr, alignment);
+ return ptr;
+}
+
+#else
+
+template<std::size_t alignment, typename T>
+/*[[nodiscard]]*/ constexpr T* assume_aligned(T *ptr) noexcept { return ptr; }
+#endif
template<typename T, typename ...Args>