AlignSize.h#

Fully qualified name: carb/AlignSize.h

File members: carb/AlignSize.h

// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.

#pragma once

#include <cstddef>
#include <cstdint>

#include "Warning.h"

#ifdef __cpp_lib_hardware_interference_size
#    include <new>
CARB_GNUC_ONLY(CARB_IGNOREWARNING_GNUC_WITH_PUSH("-Winterference-size"))
static_assert(std::hardware_destructive_interference_size == 64);
CARB_GNUC_ONLY(CARB_IGNOREWARNING_GNUC_POP)
#endif
#define CARB_CACHELINE_SIZE (64)

#define CARB_COUNTOF(a) carb::countOf(a)

#define CARB_COUNTOF32(a) uint32_t(carb::countOf(a))

#define CARB_OFFSETOF(a) carb::offsetOf(&a)

#define CARB_INCLUDES_MEMBER(sizeOfStruct, member) carb::includesMember(sizeOfStruct, &member)

#if !CARB_TOOLCHAIN_CLANG || defined(DOXYGEN_BUILD)
#    define CARB_OFFSETOF2(t, m) (offsetof(t, m))
#else
// Workaround for CLANG+MSC Library issue (https://github.com/microsoft/STL/issues/3311)
#    define CARB_OFFSETOF2(t, m) (__builtin_offsetof(t, m))
#endif

#if CARB_COMPILER_MSC || defined(DOXYGEN_BUILD)
#    define CARB_ALIGN_OF(T) __alignof(T)
#elif CARB_COMPILER_GNUC
#    define CARB_ALIGN_OF(T) __alignof__(T)
#else
CARB_UNSUPPORTED_COMPILER();
#endif

#define CARB_ALIGN(x, alignment) carb::align(x, alignment)

#define CARB_ALIGNED_SIZE(size, alignment) carb::alignedSize(size, alignment)

#define CARB_ALIGN_AS(T) alignas(T)

#define CARB_CACHELINE_ALIGN CARB_ALIGN_AS(CARB_CACHELINE_SIZE)

#ifndef DOXYGEN_BUILD
namespace carb
{
template <typename T, size_t N>
constexpr size_t countOf(T const (&)[N])
{
    return N;
}

template <typename T, typename U>
constexpr uint32_t offsetOf(U T::*member)
{
    CARB_IGNOREWARNING_GNUC_PUSH
#    if CARB_TOOLCHAIN_CLANG && __clang_major__ >= 13 // this error is issued on clang 13
    CARB_IGNOREWARNING_GNUC_WITH_PUSH("-Wnull-pointer-subtraction")
#    endif
    return (uint32_t)((char*)&((T*)nullptr->*member) - (char*)nullptr);
    CARB_IGNOREWARNING_GNUC_POP
}

template <typename T, typename U>
constexpr uint32_t includesMember(size_t sizeOfStruct, U T::*member)
{
    CARB_IGNOREWARNING_GNUC_PUSH
#    if CARB_TOOLCHAIN_CLANG && __clang_major__ >= 13 // this error is issued on clang 13
    CARB_IGNOREWARNING_GNUC_WITH_PUSH("-Wnull-pointer-subtraction")
#    endif
    return sizeOfStruct >= offsetOf(member) + sizeof(U);
    CARB_IGNOREWARNING_GNUC_POP
}

template <typename T>
constexpr T align(T x, size_t alignment)
{
    return (T)(((size_t)x + alignment - 1) / alignment * alignment);
}

template <typename T>
T* align(T* x, size_t alignment)
{
    return (T*)(((size_t)x + alignment - 1) / alignment * alignment);
}

template <typename T>
constexpr T alignedSize(const T& size, uint32_t alignment)
{
    return ((size + alignment - 1) / alignment) * alignment;
}

} // namespace carb
#endif