include/wrenbind17/map.hpp

include/wrenbind17/map.hpp #

Namespaces #

Name
wrenbind17

Classes #

Name
class wrenbind17::Map Holds native Wren map.

Source code #

#pragma once

#include "method.hpp"
#include "pop.hpp"
#include "push.hpp"

namespace wrenbind17 {
    class Map {
    public:
        Map() {
        }
        Map(const std::shared_ptr<Handle>& handle) : handle(handle) {
        }
        ~Map() {
            reset();
        }

        Handle& getHandle() {
            return *handle;
        }

        const Handle& getHandle() const {
            return *handle;
        }

        operator bool() const {
            return handle.operator bool();
        }

        void reset() {
            handle.reset();
        }

        template <typename Key> bool contains(const Key& key) const {
            if (const auto ptr = handle->getVmWeak().lock()) {
                wrenEnsureSlots(ptr.get(), 2);
                wrenSetSlotHandle(ptr.get(), 0, handle->getHandle());
                detail::PushHelper<Key>::f(ptr.get(), 1, key);
                return wrenGetMapContainsKey(ptr.get(), 0, 1);
            } else {
                throw RuntimeError("Invalid handle");
            }
        }

        template <typename T, typename Key> T get(const Key& key) const {
            if (const auto ptr = handle->getVmWeak().lock()) {
                wrenEnsureSlots(ptr.get(), 3);
                wrenSetSlotHandle(ptr.get(), 0, handle->getHandle());
                detail::PushHelper<Key>::f(ptr.get(), 1, key);
                if (!wrenGetMapContainsKey(ptr.get(), 0, 1)) {
                    throw NotFound();
                }
                wrenGetMapValue(ptr.get(), 0, 1, 2);
                return detail::PopHelper<T>::f(ptr.get(), 2);
            } else {
                throw RuntimeError("Invalid handle");
            }
        }

        template <typename Key> bool erase(const Key& key) const {
            if (const auto ptr = handle->getVmWeak().lock()) {
                wrenEnsureSlots(ptr.get(), 3);
                wrenSetSlotHandle(ptr.get(), 0, handle->getHandle());
                detail::PushHelper<Key>::f(ptr.get(), 1, key);
                wrenRemoveMapValue(ptr.get(), 0, 1, 2);
                return !detail::is<std::nullptr_t>(ptr.get(), 2);
            } else {
                throw RuntimeError("Invalid handle");
            }
        }

        size_t count() const {
            if (const auto ptr = handle->getVmWeak().lock()) {
                wrenEnsureSlots(ptr.get(), 1);
                wrenSetSlotHandle(ptr.get(), 0, handle->getHandle());
                return wrenGetMapCount(ptr.get(), 0);
            } else {
                throw RuntimeError("Invalid handle");
            }
        }

    private:
        std::shared_ptr<Handle> handle;
    };

    template <> inline Map detail::getSlot<Map>(WrenVM* vm, const int idx) {
        validate<WrenType::WREN_TYPE_MAP>(vm, idx);
        return Map(std::make_shared<Handle>(getSharedVm(vm), wrenGetSlotHandle(vm, idx)));
    }

    template <> inline bool detail::is<Map>(WrenVM* vm, const int idx) {
        return wrenGetSlotType(vm, idx) == WREN_TYPE_MAP;
    }

    template <> inline void detail::PushHelper<Map>::f(WrenVM* vm, int idx, const Map& value) {
        wrenSetSlotHandle(value.getHandle().getVm(), idx, value.getHandle().getHandle());
    }

    template <> inline void detail::PushHelper<Map>::f(WrenVM* vm, int idx, Map&& value) {
        wrenSetSlotHandle(value.getHandle().getVm(), idx, value.getHandle().getHandle());
    }

    template <> inline void detail::PushHelper<const Map>::f(WrenVM* vm, int idx, const Map value) {
        wrenSetSlotHandle(value.getHandle().getVm(), idx, value.getHandle().getHandle());
    }

    template <> inline void detail::PushHelper<const Map&>::f(WrenVM* vm, int idx, const Map& value) {
        wrenSetSlotHandle(value.getHandle().getVm(), idx, value.getHandle().getHandle());
    }

    template <> inline void detail::PushHelper<Map&>::f(WrenVM* vm, int idx, Map& value) {
        wrenSetSlotHandle(value.getHandle().getVm(), idx, value.getHandle().getHandle());
    }
} // namespace wrenbind17

Updated on 17 October 2023 at 12:26:25 UTC