carb/variant/VariantTypes.h
File members: carb/variant/VariantTypes.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 "../RString.h"
#include "../IObject.h"
#include "../../omni/String.h"
#include "../../omni/detail/PointerIterator.h"
namespace carb
{
namespace variant
{
constexpr RString eNull{ carb::eRString::RS_null };
constexpr RString eBool{ carb::eRString::RS_bool };
constexpr RString eUInt8{ carb::eRString::RS_uint8 };
constexpr RString eUInt16{ carb::eRString::RS_uint16 };
constexpr RString eUInt32{ carb::eRString::RS_uint32 };
constexpr RString eUInt64{ carb::eRString::RS_uint64 };
constexpr RString eInt8{ carb::eRString::RS_int8 };
constexpr RString eInt16{ carb::eRString::RS_int16 };
constexpr RString eInt32{ carb::eRString::RS_int32 };
constexpr RString eInt64{ carb::eRString::RS_int64 };
constexpr RString eFloat{ carb::eRString::RS_float };
constexpr RString eDouble{ carb::eRString::RS_double };
constexpr RString eString{ carb::eRString::RS_string };
constexpr RString eCharPtr{ carb::eRString::RS_charptr };
constexpr RString eDictionary{ carb::eRString::RS_dictionary };
constexpr RString eVariantPair{ carb::eRString::RS_variant_pair };
constexpr RString eVariantArray{ carb::eRString::RS_variant_array };
constexpr RString eVariantMap{ carb::eRString::RS_variant_map };
constexpr RString eRString{ carb::eRString::RS_RString };
constexpr RString eRStringU{ carb::eRString::RS_RStringU };
constexpr RString eRStringKey{ carb::eRString::RS_RStringKey };
constexpr RString eRStringUKey{ carb::eRString::RS_RStringUKey };
struct VTable;
class Variant;
struct VariantData
{
const VTable* vtable;
void* data;
};
CARB_ASSERT_INTEROP_SAFE(VariantData);
struct VTable
{
uint32_t sizeOf;
RString typeName;
void (*Destructor)(VariantData* self) noexcept;
VariantData (*Copy)(const VariantData* self) noexcept;
bool (*Equals)(const VariantData* self, const VariantData* other) noexcept;
omni::string (*ToString)(const VariantData* self) noexcept;
bool (*ConvertTo)(const VariantData* self, const VTable* newtype, VariantData* out) noexcept;
size_t (*Hash)(const VariantData* self) noexcept;
// Note to maintainers: adding new functions here does not necessarily require a version change for IVariant. Add a
// `struct traits` function that performs a default behavior if the function is `nullptr` or if the `sizeOf` is less
// than the offset of your new member. All calls to the v-table function should happen in the new `traits` function.
};
CARB_ASSERT_INTEROP_SAFE(VTable);
class VariantArray : public IObject
{
public:
using iterator = omni::detail::PointerIterator<Variant*, VariantArray>;
using const_iterator = omni::detail::PointerIterator<const Variant*, VariantArray>;
virtual Variant* data() noexcept = 0;
virtual const Variant* data() const noexcept = 0;
virtual size_t size() const noexcept = 0;
virtual void push_back(Variant v) noexcept = 0;
virtual bool insert(size_t offset, Variant v) noexcept = 0;
virtual bool erase(size_t offset) noexcept = 0;
virtual bool pop_back() noexcept = 0;
virtual void assign(const Variant* p, size_t count) noexcept = 0;
virtual void reserve(size_t count) noexcept = 0;
virtual void resize(size_t count) noexcept = 0;
virtual size_t capacity() const noexcept = 0;
void clear() noexcept;
bool empty() const noexcept;
Variant& at(size_t index);
const Variant& at(size_t index) const;
Variant& operator[](size_t index) noexcept;
const Variant& operator[](size_t index) const noexcept;
Variant& front() noexcept;
const Variant& front() const noexcept;
Variant& back() noexcept;
const Variant& back() const noexcept;
iterator begin() noexcept;
iterator end() noexcept;
const_iterator begin() const noexcept;
const_iterator end() const noexcept;
};
using VariantArrayPtr = ObjectPtr<VariantArray>;
struct KeyValuePair;
class VariantMap : public IObject
{
public:
using key_type = Variant;
using mapped_type = Variant;
using value_type = KeyValuePair;
using size_type = size_t;
using difference_type = ptrdiff_t;
using reference = value_type&;
using const_reference = const value_type&;
using pointer = value_type*;
using const_pointer = const value_type*;
// clang-format off
#ifndef DOXYGEN_SHOULD_SKIP_THIS
private:
class iter_base
{
public:
constexpr iter_base() noexcept = default;
bool operator == (const iter_base& other) const noexcept { CARB_ASSERT(owner == other.owner); return where == other.where; }
bool operator != (const iter_base& other) const noexcept { CARB_ASSERT(owner == other.owner); return where != other.where; }
protected:
constexpr iter_base(const VariantMap* owner_, pointer where_) noexcept : owner(owner_), where(where_) {}
const VariantMap* owner{ nullptr };
pointer where{ nullptr };
};
public:
class const_find_iterator : public iter_base
{
using Base = iter_base;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = VariantMap::value_type;
using difference_type = VariantMap::difference_type;
using pointer = VariantMap::const_pointer;
using reference = VariantMap::const_reference;
constexpr const_find_iterator() noexcept = default;
reference operator * () const noexcept { CARB_ASSERT(this->where); return *this->where; }
pointer operator -> () const noexcept { CARB_ASSERT(this->where); return this->where; }
const_find_iterator& operator ++ () noexcept { incr(); return *this; }
const_find_iterator operator ++ (int) noexcept { const_find_iterator i{ *this }; incr(); return i; }
protected:
friend class VariantMap;
constexpr const_find_iterator(const VariantMap* owner_, value_type* where_) noexcept : Base(owner_, where_) {}
void incr() { CARB_ASSERT(this->owner && this->where); this->where = this->owner->findNext(this->where); }
};
class find_iterator : public const_find_iterator
{
using Base = const_find_iterator;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = VariantMap::value_type;
using difference_type = VariantMap::difference_type;
using pointer = VariantMap::pointer;
using reference = VariantMap::reference;
constexpr find_iterator() noexcept = default;
reference operator * () const noexcept { CARB_ASSERT(this->where); return *this->where; }
pointer operator -> () const noexcept { CARB_ASSERT(this->where); return this->where; }
find_iterator& operator ++ () noexcept { this->incr(); return *this; }
find_iterator operator ++ (int) noexcept { find_iterator i{ *this }; this->incr(); return i; }
protected:
friend class VariantMap;
constexpr find_iterator(const VariantMap* owner_, value_type* where_) noexcept : Base(owner_, where_) {}
};
class const_iterator : public iter_base
{
using Base = iter_base;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = VariantMap::value_type;
using difference_type = VariantMap::difference_type;
using pointer = VariantMap::const_pointer;
using reference = VariantMap::const_reference;
constexpr const_iterator() noexcept = default;
reference operator * () const noexcept { CARB_ASSERT(this->where); return *this->where; }
pointer operator -> () const noexcept { CARB_ASSERT(this->where); return this->where; }
const_iterator& operator ++ () noexcept { incr(); return *this;}
const_iterator operator ++ (int) noexcept { const_iterator i{ *this }; incr(); return i; }
protected:
friend class VariantMap;
constexpr const_iterator(const VariantMap* owner_, value_type* where_) noexcept : Base{ owner_, where_ } {}
void incr() { CARB_ASSERT(this->owner && this->where); this->where = this->owner->iterNext(this->where); }
};
class iterator : public const_iterator
{
using Base = const_iterator;
public:
using iterator_category = std::forward_iterator_tag;
using value_type = VariantMap::value_type;
using difference_type = VariantMap::difference_type;
using pointer = VariantMap::pointer;
using reference = VariantMap::reference;
constexpr iterator() noexcept = default;
reference operator * () const noexcept { CARB_ASSERT(this->where); return *this->where; }
pointer operator -> () const noexcept { CARB_ASSERT(this->where); return this->where; }
iterator& operator ++ () noexcept { this->incr(); return *this; }
iterator operator ++ (int) noexcept { iterator i{ *this }; this->incr(); return i; }
protected:
friend class VariantMap;
constexpr iterator(const VariantMap* owner_, value_type* where_) noexcept : Base(owner_, where_) {}
};
#endif
// clang-format on
const_iterator cbegin() const noexcept;
const_iterator begin() const noexcept;
iterator begin() noexcept;
const_iterator cend() const noexcept;
const_iterator end() const noexcept;
iterator end() noexcept;
bool empty() const noexcept;
virtual size_t size() const noexcept = 0;
std::pair<iterator, bool> insert(const Variant& key, Variant value);
size_t erase(const Variant& key) noexcept;
iterator erase(const_iterator pos) noexcept;
find_iterator erase(const_find_iterator pos) noexcept;
find_iterator find(const Variant& key) noexcept;
const_find_iterator find(const Variant& key) const noexcept;
bool contains(const Variant& key) const noexcept;
size_t count(const Variant& key) const noexcept;
#if CARB_EXCEPTIONS_ENABLED || defined(DOXYGEN_BUILD)
mapped_type& at(const Variant& key);
const mapped_type& at(const Variant& key) const;
#endif
mapped_type& operator[](const Variant& key);
virtual void clear() noexcept = 0;
virtual size_t capacity() const noexcept = 0;
virtual void reserve(size_t n) noexcept = 0;
virtual void rehash(size_t n) noexcept = 0;
private:
virtual KeyValuePair* internalInsert(const Variant& key, bool& success) noexcept = 0;
virtual void internalErase(const KeyValuePair*) noexcept = 0;
virtual KeyValuePair* internalFind(const Variant& key) const noexcept = 0;
virtual KeyValuePair* internalBegin() const noexcept = 0;
virtual KeyValuePair* iterNext(KeyValuePair*) const noexcept = 0;
virtual KeyValuePair* findNext(KeyValuePair*) const noexcept = 0;
};
using VariantMapPtr = ObjectPtr<VariantMap>;
template <class T, class Enable = void>
struct Translator;
} // namespace variant
} // namespace carb