carb/Version.h
File members: carb/Version.h
// Copyright (c) 2018-2024, NVIDIA CORPORATION. All rights reserved.
//
// NVIDIA CORPORATION and its licensors retain all intellectual property
// and proprietary rights in and to this software, related documentation
// and any modifications thereto. Any use, reproduction, disclosure or
// distribution of this software and related documentation without an express
// license agreement from NVIDIA CORPORATION is strictly prohibited.
//
#pragma once
#include <cinttypes>
#include <cstdint>
#include <cstdio>
#include <type_traits>
// Note: Ideally this would be in Defines.h, but there is a weird circular dependency:
// Defines.h -> assert/IAssert.h -> Interface.h -> Version.h
#define CARB_ASSERT_INTEROP_SAFE(...) \
static_assert(std::is_standard_layout<__VA_ARGS__>::value, "Must have standard layout to be interop safe"); \
static_assert(std::is_trivially_copyable<__VA_ARGS__>::value, "Must be trivially copyable to be interop safe")
namespace carb
{
struct Version
{
uint32_t major;
uint32_t minor;
};
CARB_ASSERT_INTEROP_SAFE(Version);
constexpr Version fromHexVersion(uint32_t hexver) noexcept
{
return Version{ hexver >> 16, hexver & 0xffff };
}
constexpr uint32_t toHexVersion(carb::Version ver) noexcept
{
return (ver.major << 16) | (ver.minor);
}
constexpr bool operator<(const Version& lhs, const Version& rhs) noexcept
{
if (lhs.major == rhs.major)
{
return lhs.minor < rhs.minor;
}
return lhs.major < rhs.major;
}
constexpr bool operator<=(const Version& lhs, const Version& rhs) noexcept
{
if (lhs.major == rhs.major)
{
return lhs.minor <= rhs.minor;
}
return lhs.major < rhs.major;
}
constexpr bool operator==(const Version& lhs, const Version& rhs) noexcept
{
return lhs.major == rhs.major && lhs.minor == rhs.minor;
}
constexpr bool operator!=(const Version& lhs, const Version& rhs) noexcept
{
return !(lhs == rhs);
}
inline bool isVersionSemanticallyCompatible(const char* name, const Version& minimum, const Version& candidate)
{
if (minimum.major != candidate.major)
{
return false;
}
else if (minimum.major == 0)
{
// Need to special case when major is equal but zero, then any difference in minor makes them
// incompatible. See http://semver.org for details.
// the case of version 0.x (major of 0), we are only going to "warn" the user of possible
// incompatibility when a user asks for 0.x and we have an implementation 0.y (where y > x).
// see https://nvidia-omniverse.atlassian.net/browse/CC-249
if (minimum.minor > candidate.minor)
{
return false;
}
else if (minimum.minor < candidate.minor && name)
{
// using CARB_LOG maybe pointless, as logging may not be set up yet.
fprintf(stderr,
"Warning: Possible version incompatibility. Attempting to load %s with version v%" PRIu32
".%" PRIu32 " against v%" PRIu32 ".%" PRIu32 ".\n",
name, candidate.major, candidate.minor, minimum.major, minimum.minor);
}
}
else if (minimum.minor > candidate.minor)
{
return false;
}
return true;
}
} // namespace carb