carb/variant/VariantUtils.h
File members: carb/variant/VariantUtils.h
// Copyright (c) 2022-2023, 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 "VariantTypes.h"
namespace carb
{
namespace variant
{
template <class Type>
VariantData translate(Type&& type) noexcept;
struct traits
{
static void swap(VariantData& lhs, VariantData& rhs) noexcept;
static void destruct(VariantData& self) noexcept;
static VariantData copy(const VariantData& self) noexcept;
static bool equals(const VariantData& self, const VariantData& other) noexcept;
static omni::string toString(const VariantData& self) noexcept;
static bool convertTo(const VariantData& self, const VTable* newType, VariantData& out) noexcept;
static size_t hash(const VariantData& self) noexcept;
};
class Variant final : protected VariantData
{
public:
Variant() noexcept;
#ifndef DOXYGEN_BUILD
template <class T, typename std::enable_if_t<!std::is_same<std::decay_t<T>, Variant>::value, bool> = true>
#else
template <class T>
#endif
explicit Variant(T&& val) noexcept
{
// This function cannot be externally inlined due to MSVC not understanding the enable_if in the inlined
// function.
data() = translate(std::forward<T>(val));
}
~Variant() noexcept;
Variant(const Variant& other) noexcept;
Variant& operator=(const Variant& other) noexcept;
Variant(Variant&& other) noexcept;
Variant& operator=(Variant&& other) noexcept;
bool operator==(const Variant& other) const noexcept;
bool operator!=(const Variant& other) const noexcept;
bool hasValue() const noexcept;
omni::string toString() const noexcept;
size_t getHash() const noexcept;
template <class T>
cpp::optional<T> getValue() const noexcept;
template <class T>
T getValueOr(T&& fallback) const noexcept;
template <class T>
Variant convertTo() const noexcept;
const VariantData& data() const noexcept
{
return *this;
}
private:
VariantData& data() noexcept
{
return *this;
}
};
// The Variant class is intended only to add functions on top of VariantData. Therefore, the size must match.
static_assert(sizeof(Variant) == sizeof(VariantData), "");
// This is an ABI-stable representation of std::pair<Variant, Variant>, used only by Translator and internally by
// carb.variant.plugin.
struct VariantPair
{
Variant first;
Variant second;
};
static_assert(std::is_standard_layout<VariantPair>::value, ""); // not interop-safe because not trivially copyable
struct KeyValuePair
{
const Variant first;
Variant second;
};
static_assert(std::is_standard_layout<KeyValuePair>::value, ""); // not interop-safe because not trivially copyable
class Registrar
{
public:
constexpr Registrar() noexcept;
Registrar(const VTable* vtable) noexcept;
~Registrar() noexcept;
Registrar(Registrar&& other) noexcept;
Registrar& operator=(Registrar&& other) noexcept;
bool isEmpty() const noexcept;
RString getType() const noexcept;
void reset() noexcept;
private:
RString m_type;
};
} // namespace variant
namespace variant_literals
{
CARB_NODISCARD inline variant::Variant operator"" _v(unsigned long long val) noexcept
{
return variant::Variant{ val };
}
CARB_NODISCARD inline variant::Variant operator"" _v(long double val) noexcept
{
return variant::Variant{ (double)val };
}
CARB_NODISCARD inline variant::Variant operator"" _v(const char* str, size_t length) noexcept
{
CARB_UNUSED(length);
return variant::Variant{ str };
}
} // namespace variant_literals
} // namespace carb
#ifndef DOXYGEN_SHOULD_SKIP_THIS
namespace std
{
template <>
struct hash<carb::variant::Variant>
{
size_t operator()(const carb::variant::Variant& v) const noexcept
{
return v.getHash();
}
};
inline std::string to_string(const carb::variant::Variant& v)
{
auto str = v.toString();
return std::string(str.begin(), str.end());
}
} // namespace std
#endif