ISettings.h#

Fully qualified name: carb/settings/ISettings.h

File members: carb/settings/ISettings.h

// SPDX-FileCopyrightText: Copyright (c) 2019-2025 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 "../Defines.h"

#include "../InterfaceUtils.h"
#include "../dictionary/IDictionary.h"

#include <cstddef>
#include <cstdint>

#define carb_settings_ISettings_latest CARB_HEXVERSION(1, 1)
#ifndef carb_settings_ISettings
#    define carb_settings_ISettings CARB_HEXVERSION(1, 1)
#endif

namespace carb
{

namespace settings
{

struct Transaction DOXYGEN_EMPTY_CLASS;

struct ISettings
{
    CARB_PLUGIN_INTERFACE_EX("carb::settings::ISettings", carb_settings_ISettings_latest, carb_settings_ISettings)

    dictionary::ItemType(CARB_ABI* getItemType)(const char* path);

    bool(CARB_ABI* isAccessibleAs)(dictionary::ItemType itemType, const char* path);

    void(CARB_ABI* setDictionary)(const char* path);

    int64_t(CARB_ABI* getAsInt64)(const char* path);

    void(CARB_ABI* setInt64)(const char* path, int64_t value);

    int32_t getAsInt(const char* path);

    void setInt(const char* path, int32_t value);

    double(CARB_ABI* getAsFloat64)(const char* path);

    void(CARB_ABI* setFloat64)(const char* path, double value);

    float getAsFloat(const char* path);

    void setFloat(const char* path, float value);

    bool(CARB_ABI* getAsBool)(const char* path);

    void(CARB_ABI* setBool)(const char* path, bool value);

    const char*(CARB_ABI* internalCreateStringBufferFromItemValue)(const char* path, size_t* pStringLen);

    const char* createStringBufferFromItemValue(const char* path, size_t* pStringLen = nullptr) const
    {
        return internalCreateStringBufferFromItemValue(path, pStringLen);
    }

    const char*(CARB_ABI* internalGetStringBuffer)(const char* path, size_t* pStringLen);

    const char* getStringBuffer(const char* path, size_t* pStringLen = nullptr) const
    {
        return internalGetStringBuffer(path, pStringLen);
    }

    void(CARB_ABI* internalSetString)(const char* path, const char* value, size_t stringLen);

    void setString(const char* path, const char* value, size_t stringLen = size_t(-1)) const
    {
        internalSetString(path, value, stringLen);
    }

    template <typename T>
    T get(const char* path);

    template <typename T>
    void set(const char* path, T value);

    bool(CARB_ABI* isAccessibleAsArray)(const char* path);

    bool(CARB_ABI* isAccessibleAsArrayOf)(dictionary::ItemType itemType, const char* path);

    size_t(CARB_ABI* getArrayLength)(const char* path);

    dictionary::ItemType(CARB_ABI* getPreferredArrayType)(const char* path);

    int64_t(CARB_ABI* getAsInt64At)(const char* path, size_t index);

    void(CARB_ABI* setInt64At)(const char* path, size_t index, int64_t value);

    int32_t getAsIntAt(const char* path, size_t index);

    void setIntAt(const char* path, size_t index, int32_t value);

    void(CARB_ABI* getAsInt64Array)(const char* path, int64_t* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setInt64Array)(const char* path, const int64_t* array, size_t arrayLength);

    void(CARB_ABI* getAsIntArray)(const char* path, int32_t* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setIntArray)(const char* path, const int32_t* array, size_t arrayLength);

    double(CARB_ABI* getAsFloat64At)(const char* path, size_t index);

    void(CARB_ABI* setFloat64At)(const char* path, size_t index, double value);

    float getAsFloatAt(const char* path, size_t index);
    void setFloatAt(const char* path, size_t index, float value);

    void(CARB_ABI* getAsFloat64Array)(const char* path, double* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setFloat64Array)(const char* path, const double* array, size_t arrayLength);

    void(CARB_ABI* getAsFloatArray)(const char* path, float* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setFloatArray)(const char* path, const float* array, size_t arrayLength);

    bool(CARB_ABI* getAsBoolAt)(const char* path, size_t index);

    void(CARB_ABI* setBoolAt)(const char* path, size_t index, bool value);

    void(CARB_ABI* getAsBoolArray)(const char* path, bool* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setBoolArray)(const char* path, const bool* array, size_t arrayLength);

    const char*(CARB_ABI* internalCreateStringBufferFromItemValueAt)(const char* path, size_t index, size_t* pStringLen);

    const char* createStringBufferFromItemValueAt(const char* path, size_t index, size_t* pStringLen = nullptr) const
    {
        return internalCreateStringBufferFromItemValueAt(path, index, pStringLen);
    }

    const char*(CARB_ABI* internalGetStringBufferAt)(const char* path, size_t index, size_t* pStringLen);

    const char* getStringBufferAt(const char* path, size_t index, size_t* pStringLen = nullptr) const
    {
        return internalGetStringBufferAt(path, index, pStringLen);
    }

    void(CARB_ABI* internalSetStringAt)(const char* path, size_t index, const char* value, size_t stringLen);

    void setStringAt(const char* path, size_t index, const char* value, size_t stringLen = size_t(-1)) const
    {
        internalSetStringAt(path, index, value, stringLen);
    }

    void(CARB_ABI* getStringBufferArray)(const char* path, const char** arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setStringArray)(const char* path, const char* const* array, size_t arrayLength);

    template <typename SettingArrayType>
    void setArray(const char* path, const SettingArrayType* array, size_t arrayLength);

    Transaction*(CARB_ABI* createTransaction)();

    void(CARB_ABI* destroyTransaction)(Transaction* transaction);

    void(CARB_ABI* commitTransaction)(Transaction* transaction);

    void(CARB_ABI* setInt64Async)(Transaction* transaction, const char* path, int64_t value);
    void(CARB_ABI* setFloat64Async)(Transaction* transaction, const char* path, double value);
    void(CARB_ABI* setBoolAsync)(Transaction* transaction, const char* path, bool value);
    void(CARB_ABI* setStringAsync)(Transaction* transaction, const char* path, const char* value);

    dictionary::SubscriptionId*(CARB_ABI* subscribeToNodeChangeEvents)(const char* path,
                                                                       dictionary::OnNodeChangeEventFn onChangeEventFn,
                                                                       void* userData);

    dictionary::SubscriptionId*(CARB_ABI* subscribeToTreeChangeEvents)(const char* path,
                                                                       dictionary::OnTreeChangeEventFn onChangeEventFn,
                                                                       void* userData);

    void(CARB_ABI* unsubscribeToChangeEvents)(dictionary::SubscriptionId* subscriptionId);

    void(CARB_ABI* update)(const char* path,
                           const dictionary::Item* dictionary,
                           const char* dictionaryPath,
                           dictionary::OnUpdateItemFn onUpdateItemFn,
                           void* userData);

    const dictionary::Item*(CARB_ABI* getSettingsDictionary)(const char* path);

    dictionary::Item*(CARB_ABI* createDictionaryFromSettings)(const char* path);

    void(CARB_ABI* destroyItem)(const char* path);

    void(CARB_ABI* destroyStringBuffer)(const char* stringBuffer);

    void(CARB_ABI* initializeFromDictionary)(const dictionary::Item* dictionary);

    void setDefaultInt64(const char* path, int64_t value);
    void setDefaultInt(const char* path, int32_t value);
    void setDefaultFloat64(const char* path, double value);
    void setDefaultFloat(const char* path, float value);
    void setDefaultBool(const char* path, bool value);
    void setDefaultString(const char* path, const char* value);

    template <typename SettingType>
    void setDefault(const char* path, SettingType value);

    void setDefaultsFromDictionary(const char* path, const dictionary::Item* dictionary);

    void setDefaultInt64Array(const char* path, const int64_t* array, size_t arrayLength);
    void setDefaultIntArray(const char* path, const int32_t* array, size_t arrayLength);
    void setDefaultFloat64Array(const char* path, const double* array, size_t arrayLength);
    void setDefaultFloatArray(const char* path, const float* array, size_t arrayLength);
    void setDefaultBoolArray(const char* path, const bool* array, size_t arrayLength);
    void setDefaultStringArray(const char* path, const char* const* array, size_t arrayLength);

    template <typename SettingArrayType>
    void setDefaultArray(const char* path, const SettingArrayType* array, size_t arrayLength);

#if CARB_VERSION_ATLEAST(carb_settings_ISettings, 1, 1)
    dictionary::ItemType(CARB_ABI* getItemTypeS)(const cpp::string_view& path);

    bool(CARB_ABI* isAccessibleAsS)(dictionary::ItemType itemType, const cpp::string_view& path);

    void(CARB_ABI* setDictionaryS)(const cpp::string_view& path);

    int64_t(CARB_ABI* getAsInt64S)(const cpp::string_view& path);

    void(CARB_ABI* setInt64S)(const cpp::string_view& path, int64_t value);

    double(CARB_ABI* getAsFloat64S)(const cpp::string_view& path);

    void(CARB_ABI* setFloat64S)(const cpp::string_view& path, double value);

    bool(CARB_ABI* getAsBoolS)(const cpp::string_view& path);

    void(CARB_ABI* setBoolS)(const cpp::string_view& path, bool value);

    const char*(CARB_ABI* internalCreateStringBufferFromItemValueS)(const cpp::string_view& path, size_t* pStringLen);

    cpp::optional<cpp::zstring_view>(CARB_ABI* getStringBufferS)(const cpp::string_view& path);

    void(CARB_ABI* setStringS)(const cpp::string_view& path, const cpp::string_view& value);

    bool(CARB_ABI* isAccessibleAsArrayS)(const cpp::string_view& path);

    bool(CARB_ABI* isAccessibleAsArrayOfS)(dictionary::ItemType itemType, const cpp::string_view& path);

    size_t(CARB_ABI* getArrayLengthS)(const cpp::string_view& path);

    dictionary::ItemType(CARB_ABI* getPreferredArrayTypeS)(const cpp::string_view& path);

    int64_t(CARB_ABI* getAsInt64AtS)(const cpp::string_view& path, size_t index);

    void(CARB_ABI* setInt64AtS)(const cpp::string_view& path, size_t index, int64_t value);

    void(CARB_ABI* getAsInt64ArrayS)(const cpp::string_view& path, int64_t* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setInt64ArrayS)(const cpp::string_view& path, const int64_t* array, size_t arrayLength);

    void(CARB_ABI* getAsIntArrayS)(const cpp::string_view& path, int32_t* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setIntArrayS)(const cpp::string_view& path, const int32_t* array, size_t arrayLength);

    double(CARB_ABI* getAsFloat64AtS)(const cpp::string_view& path, size_t index);

    void(CARB_ABI* setFloat64AtS)(const cpp::string_view& path, size_t index, double value);

    void(CARB_ABI* getAsFloat64ArrayS)(const cpp::string_view& path, double* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setFloat64ArrayS)(const cpp::string_view& path, const double* array, size_t arrayLength);

    void(CARB_ABI* getAsFloatArrayS)(const cpp::string_view& path, float* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setFloatArrayS)(const cpp::string_view& path, const float* array, size_t arrayLength);

    bool(CARB_ABI* getAsBoolAtS)(const cpp::string_view& path, size_t index);

    void(CARB_ABI* setBoolAtS)(const cpp::string_view& path, size_t index, bool value);

    void(CARB_ABI* getAsBoolArrayS)(const cpp::string_view& path, bool* arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setBoolArrayS)(const cpp::string_view& path, const bool* array, size_t arrayLength);

    const char*(CARB_ABI* internalCreateStringBufferFromItemValueAtS)(const cpp::string_view& path,
                                                                      size_t index,
                                                                      size_t* pStringLen);

    const char* createStringBufferFromItemValueAtS(const cpp::string_view& path,
                                                   size_t index,
                                                   size_t* pStringLen = nullptr) const
    {
        return internalCreateStringBufferFromItemValueAtS(path, index, pStringLen);
    }

    cpp::optional<cpp::zstring_view>(CARB_ABI* getStringBufferAtS)(const cpp::string_view& path, size_t index);

    void(CARB_ABI* setStringAtS)(const cpp::string_view& path, size_t index, const cpp::string_view& value);

    void(CARB_ABI* getStringBufferArrayS)(const cpp::string_view& path, const char** arrayOut, size_t arrayBufferLength);

    void(CARB_ABI* setStringArrayS)(const cpp::string_view& path, const char* const* array, size_t arrayLength);

    void(CARB_ABI* setInt64AsyncS)(Transaction* transaction, const cpp::string_view& path, int64_t value);
    void(CARB_ABI* setFloat64AsyncS)(Transaction* transaction, const cpp::string_view& path, double value);
    void(CARB_ABI* setBoolAsyncS)(Transaction* transaction, const cpp::string_view& path, bool value);
    void(CARB_ABI* setStringAsyncS)(Transaction* transaction, const cpp::string_view& path, const cpp::string_view& value);

    dictionary::SubscriptionId*(CARB_ABI* subscribeToNodeChangeEventsS)(const cpp::string_view& path,
                                                                        dictionary::OnNodeChangeEventFn onChangeEventFn,
                                                                        void* userData);

    dictionary::SubscriptionId*(CARB_ABI* subscribeToTreeChangeEventsS)(const cpp::string_view& path,
                                                                        dictionary::OnTreeChangeEventFn onChangeEventFn,
                                                                        void* userData);

    void(CARB_ABI* updateS)(const cpp::string_view& path,
                            const dictionary::Item* dictionary,
                            const cpp::string_view& dictionaryPath,
                            dictionary::OnUpdateItemFn onUpdateItemFn,
                            void* userData);

    const dictionary::Item*(CARB_ABI* getSettingsDictionaryS)(const cpp::string_view& path);

    dictionary::Item*(CARB_ABI* createDictionaryFromSettingsS)(const cpp::string_view& path);

    void(CARB_ABI* destroyItemS)(const cpp::string_view& path);

    // Non-CARB_ABI string_view functions

    int32_t getAsIntS(cpp::string_view path);

    void setIntS(cpp::string_view path, int32_t value);

    float getAsFloatS(cpp::string_view path);

    void setFloatS(cpp::string_view path, float value);

    int32_t getAsIntAtS(cpp::string_view path, size_t index);

    const char* createStringBufferFromItemValueS(cpp::string_view path, size_t* pStringLen = nullptr) const
    {
        return internalCreateStringBufferFromItemValueS(path, pStringLen);
    }

    template <typename T>
    T get(cpp::string_view path);

    template <typename T>
    void set(cpp::string_view path, T value);

    template <typename SettingArrayType>
    void setArray(cpp::string_view path, const SettingArrayType* array, size_t arrayLength);

    void setDefaultInt64S(cpp::string_view path, int64_t value);

    void setDefaultIntS(cpp::string_view path, int32_t value);

    void setDefaultFloat64S(cpp::string_view path, double value);

    void setDefaultFloatS(cpp::string_view path, float value);

    void setDefaultBoolS(cpp::string_view path, bool value);

    void setDefaultStringS(cpp::string_view path, cpp::string_view value);

    template <typename SettingType>
    void setDefault(cpp::string_view path, SettingType value);

    void setDefaultInt64ArrayS(cpp::string_view path, const int64_t* array, size_t arrayLength);

    void setDefaultIntArrayS(cpp::string_view path, const int32_t* array, size_t arrayLength);

    void setDefaultFloat64ArrayS(cpp::string_view path, const double* array, size_t arrayLength);

    void setDefaultFloatArrayS(cpp::string_view path, const float* array, size_t arrayLength);

    void setDefaultBoolArrayS(cpp::string_view path, const bool* array, size_t arrayLength);

    void setDefaultStringArrayS(cpp::string_view path, const char* const* array, size_t arrayLength);

    template <typename SettingArrayType>
    void setDefaultArray(cpp::string_view path, const SettingArrayType* array, size_t arrayLength);

    void setDefaultsFromDictionaryS(cpp::string_view path, const dictionary::Item* dictionary);

#endif
};

class ScopedWrite : public carb::dictionary::ScopedWrite
{
public:
    ScopedWrite()
        : carb::dictionary::ScopedWrite(
              *carb::getCachedInterface<dictionary::IDictionary>(),
              const_cast<dictionary::Item*>(carb::getCachedInterface<settings::ISettings>()->getSettingsDictionary("/")))
    {
    }

    ScopedWrite(ISettings* settings, dictionary::IDictionary* dict)
        : carb::dictionary::ScopedWrite(*dict, const_cast<dictionary::Item*>(settings->getSettingsDictionary("/")))
    {
    }

    ~ScopedWrite() = default;
    CARB_PREVENT_COPY_AND_MOVE(ScopedWrite);
};

class ScopedRead : public carb::dictionary::ScopedRead
{
public:
    ScopedRead()
        : carb::dictionary::ScopedRead(*carb::getCachedInterface<dictionary::IDictionary>(),
                                       carb::getCachedInterface<settings::ISettings>()->getSettingsDictionary("/"))
    {
    }

    ScopedRead(ISettings* settings, dictionary::IDictionary* dict)
        : carb::dictionary::ScopedRead(*dict, const_cast<dictionary::Item*>(settings->getSettingsDictionary("/")))
    {
    }

    ~ScopedRead() = default;
    CARB_PREVENT_COPY_AND_MOVE(ScopedRead);
};

inline int32_t ISettings::getAsInt(const char* path)
{
    auto val = getAsInt64(path);
    CARB_ASSERT(val >= INT_MIN && val <= INT_MAX);
    return int32_t(val);
}

inline void ISettings::setInt(const char* path, int32_t value)
{
    setInt64(path, (int64_t)value);
}

inline float ISettings::getAsFloat(const char* path)
{
    return (float)getAsFloat64(path);
}

inline void ISettings::setFloat(const char* path, float value)
{
    setFloat64(path, (double)value);
}

inline int32_t ISettings::getAsIntAt(const char* path, size_t index)
{
    auto val = getAsInt64At(path, index);
    CARB_ASSERT(val >= INT_MIN && val <= INT_MAX);
    return int32_t(val);
}
inline void ISettings::setIntAt(const char* path, size_t index, int32_t value)
{
    setInt64At(path, index, (int64_t)value);
}

inline float ISettings::getAsFloatAt(const char* path, size_t index)
{
    return (float)getAsFloat64At(path, index);
}

inline void ISettings::setFloatAt(const char* path, size_t index, float value)
{
    setFloat64At(path, index, (double)value);
}

inline void ISettings::setDefaultInt64(const char* path, int64_t value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setInt64(path, value);
    }
}
inline void ISettings::setDefaultInt(const char* path, int32_t value)
{
    setDefaultInt64(path, (int64_t)value);
}

inline void ISettings::setDefaultFloat64(const char* path, double value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloat64(path, value);
    }
}
inline void ISettings::setDefaultFloat(const char* path, float value)
{
    setDefaultFloat64(path, (double)value);
}

inline void ISettings::setDefaultBool(const char* path, bool value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setBool(path, value);
    }
}

inline void ISettings::setDefaultString(const char* path, const char* value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setString(path, value);
    }
}

inline void ISettings::setDefaultsFromDictionary(const char* path, const dictionary::Item* dictionary)
{
    if (dictionary)
    {
        update(path, dictionary, nullptr, dictionary::kUpdateItemKeepOriginal, nullptr);
    }
}

inline void ISettings::setDefaultInt64Array(const char* path, const int64_t* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setInt64Array(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultIntArray(const char* path, const int32_t* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setIntArray(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultFloat64Array(const char* path, const double* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloat64Array(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultFloatArray(const char* path, const float* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloatArray(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultBoolArray(const char* path, const bool* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setBoolArray(path, array, arrayLength);
    }
}
inline void ISettings::setDefaultStringArray(const char* path, const char* const* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemType(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setStringArray(path, array, arrayLength);
    }
}

#ifndef DOXYGEN_BUILD
template <>
inline int32_t ISettings::get<int>(const char* path)
{
    return getAsInt(path);
}

template <>
inline int64_t ISettings::get<int64_t>(const char* path)
{
    return getAsInt64(path);
}

template <>
inline float ISettings::get<float>(const char* path)
{
    return getAsFloat(path);
}

template <>
inline double ISettings::get<double>(const char* path)
{
    return getAsFloat64(path);
}

template <>
inline bool ISettings::get<bool>(const char* path)
{
    return getAsBool(path);
}

template <>
inline const char* ISettings::get<const char*>(const char* path)
{
    return getStringBuffer(path);
}

template <>
inline void ISettings::set<int32_t>(const char* path, int32_t value)
{
    setInt(path, value);
}

template <>
inline void ISettings::set<int64_t>(const char* path, int64_t value)
{
    setInt64(path, value);
}

template <>
inline void ISettings::set<float>(const char* path, float value)
{
    setFloat(path, value);
}

template <>
inline void ISettings::set<double>(const char* path, double value)
{
    setFloat64(path, value);
}

template <>
inline void ISettings::set<bool>(const char* path, bool value)
{
    setBool(path, value);
}

template <>
inline void ISettings::set<const char*>(const char* path, const char* value)
{
    setString(path, value);
}

template <>
inline void ISettings::setArray(const char* path, const bool* array, size_t arrayLength)
{
    setBoolArray(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const int32_t* array, size_t arrayLength)
{
    setIntArray(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const int64_t* array, size_t arrayLength)
{
    setInt64Array(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const float* array, size_t arrayLength)
{
    setFloatArray(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const double* array, size_t arrayLength)
{
    setFloat64Array(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(const char* path, const char* const* array, size_t arrayLength)
{
    setStringArray(path, array, arrayLength);
}

template <>
inline void ISettings::setDefault(const char* path, bool value)
{
    setDefaultBool(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, int32_t value)
{
    setDefaultInt(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, int64_t value)
{
    setDefaultInt64(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, float value)
{
    setDefaultFloat(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, double value)
{
    setDefaultFloat64(path, value);
}

template <>
inline void ISettings::setDefault(const char* path, const char* value)
{
    setDefaultString(path, value);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const bool* array, size_t arrayLength)
{
    setDefaultBoolArray(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const int32_t* array, size_t arrayLength)
{
    setDefaultIntArray(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const int64_t* array, size_t arrayLength)
{
    setDefaultInt64Array(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const float* array, size_t arrayLength)
{
    setDefaultFloatArray(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const double* array, size_t arrayLength)
{
    setDefaultFloat64Array(settingsPath, array, arrayLength);
}

template <>
inline void ISettings::setDefaultArray(const char* settingsPath, const char* const* array, size_t arrayLength)
{
    setDefaultStringArray(settingsPath, array, arrayLength);
}
#endif

#if CARB_VERSION_ATLEAST(carb_settings_ISettings, 1, 1)
inline int32_t ISettings::getAsIntS(cpp::string_view path)
{
    auto val = getAsInt64S(path);
    CARB_ASSERT(val >= INT_MIN && val <= INT_MAX);
    return int32_t(val);
}

inline void ISettings::setIntS(cpp::string_view path, int32_t value)
{
    setInt64S(path, (int64_t)value);
}

inline float ISettings::getAsFloatS(cpp::string_view path)
{
    return (float)getAsFloat64S(path);
}

inline void ISettings::setFloatS(cpp::string_view path, float value)
{
    setFloat64S(path, (double)value);
}

inline int32_t ISettings::getAsIntAtS(cpp::string_view path, size_t index)
{
    auto val = getAsInt64AtS(path, index);
    CARB_ASSERT(val >= INT_MIN && val <= INT_MAX);
    return int32_t(val);
}

inline void ISettings::setDefaultIntS(cpp::string_view path, int32_t value)
{
    setDefaultInt64S(path, (int64_t)value);
}

inline void ISettings::setDefaultInt64S(cpp::string_view path, int64_t value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setInt64S(path, value);
    }
}

inline void ISettings::setDefaultFloat64S(cpp::string_view path, double value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloat64S(path, value);
    }
}

inline void ISettings::setDefaultFloatS(cpp::string_view path, float value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloatS(path, value);
    }
}

inline void ISettings::setDefaultBoolS(cpp::string_view path, bool value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setBoolS(path, value);
    }
}

inline void ISettings::setDefaultStringS(cpp::string_view path, cpp::string_view value)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setStringS(path, value);
    }
}

inline void ISettings::setDefaultInt64ArrayS(cpp::string_view path, const int64_t* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setInt64ArrayS(path, array, arrayLength);
    }
}

inline void ISettings::setDefaultIntArrayS(cpp::string_view path, const int32_t* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setIntArrayS(path, array, arrayLength);
    }
}

inline void ISettings::setDefaultFloat64ArrayS(cpp::string_view path, const double* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloat64ArrayS(path, array, arrayLength);
    }
}

inline void ISettings::setDefaultFloatArrayS(cpp::string_view path, const float* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setFloatArrayS(path, array, arrayLength);
    }
}

inline void ISettings::setDefaultBoolArrayS(cpp::string_view path, const bool* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setBoolArrayS(path, array, arrayLength);
    }
}

inline void ISettings::setDefaultStringArrayS(cpp::string_view path, const char* const* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        setStringArrayS(path, array, arrayLength);
    }
}

inline void ISettings::setDefaultsFromDictionaryS(cpp::string_view path, const dictionary::Item* dictionary)
{
    if (dictionary)
    {
        updateS(path, dictionary, cpp::string_view{}, dictionary::kUpdateItemKeepOriginal, nullptr);
    }
}

#    ifndef DOXYGEN_BUILD

template <>
inline int32_t ISettings::get<int>(cpp::string_view path)
{
    return getAsIntS(path);
}

template <>
inline int64_t ISettings::get<int64_t>(cpp::string_view path)
{
    return getAsInt64S(path);
}

template <>
inline float ISettings::get<float>(cpp::string_view path)
{
    return getAsFloatS(path);
}

template <>
inline double ISettings::get<double>(cpp::string_view path)
{
    return getAsFloat64S(path);
}

template <>
inline bool ISettings::get<bool>(cpp::string_view path)
{
    return getAsBoolS(path);
}

template <>
inline const char* ISettings::get<const char*>(cpp::string_view path)
{
    auto result = getStringBufferS(path);
    return result ? result->c_str() : nullptr;
}

template <>
inline void ISettings::set<int32_t>(cpp::string_view path, int32_t value)
{
    setIntS(path, value);
}

template <>
inline void ISettings::set<int64_t>(cpp::string_view path, int64_t value)
{
    setInt64S(path, value);
}

template <>
inline void ISettings::set<float>(cpp::string_view path, float value)
{
    setFloatS(path, value);
}

template <>
inline void ISettings::set<double>(cpp::string_view path, double value)
{
    setFloat64S(path, value);
}

template <>
inline void ISettings::set<bool>(cpp::string_view path, bool value)
{
    setBoolS(path, value);
}

template <>
inline void ISettings::set<cpp::string_view>(cpp::string_view path, cpp::string_view value)
{
    setStringS(path, value);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const bool* array, size_t arrayLength)
{
    setBoolArrayS(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const int32_t* array, size_t arrayLength)
{
    setIntArrayS(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const int64_t* array, size_t arrayLength)
{
    setInt64ArrayS(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const float* array, size_t arrayLength)
{
    setFloatArrayS(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const double* array, size_t arrayLength)
{
    setFloat64ArrayS(path, array, arrayLength);
}

template <>
inline void ISettings::setArray(cpp::string_view path, const char* const* array, size_t arrayLength)
{
    setStringArrayS(path, array, arrayLength);
}

template <>
inline void ISettings::setDefault(cpp::string_view path, bool value)
{
    setDefaultBoolS(path, value);
}

template <>
inline void ISettings::setDefault(cpp::string_view path, int32_t value)
{
    setDefaultIntS(path, value);
}

template <>
inline void ISettings::setDefault(cpp::string_view path, int64_t value)
{
    setDefaultInt64S(path, value);
}

template <>
inline void ISettings::setDefault(cpp::string_view path, float value)
{
    setDefaultFloatS(path, value);
}

template <>
inline void ISettings::setDefault(cpp::string_view path, double value)
{
    setDefaultFloat64S(path, value);
}

template <>
inline void ISettings::setDefault(cpp::string_view path, cpp::string_view value)
{
    setDefaultStringS(path, value);
}

template <typename SettingArrayType>
inline void ISettings::setDefaultArray(cpp::string_view path, const SettingArrayType* array, size_t arrayLength)
{
    ScopedWrite writeLock;
    dictionary::ItemType itemType = getItemTypeS(path);
    if (itemType == dictionary::ItemType::eCount)
    {
        if constexpr (std::is_same_v<SettingArrayType, bool>)
        {
            setBoolArrayS(path, array, arrayLength);
        }
        else if constexpr (std::is_same_v<SettingArrayType, int32_t>)
        {
            setIntArrayS(path, array, arrayLength);
        }
        else if constexpr (std::is_same_v<SettingArrayType, int64_t>)
        {
            setInt64ArrayS(path, array, arrayLength);
        }
        else if constexpr (std::is_same_v<SettingArrayType, float>)
        {
            setFloatArrayS(path, array, arrayLength);
        }
        else if constexpr (std::is_same_v<SettingArrayType, double>)
        {
            setFloat64ArrayS(path, array, arrayLength);
        }
        else if constexpr (std::is_same_v<SettingArrayType, const char*>)
        {
            setStringArrayS(path, array, arrayLength);
        }
        else
        {
            static_assert(sizeof(SettingArrayType) == 0, "Unsupported type for setDefaultArray");
        }
    }
}
#    endif
#endif

} // namespace settings
} // namespace carb