include/wrenbind17/any.hpp
#
Namespaces
#
Classes
#
Source code
#
#pragma once
#include <typeinfo>
#include <memory>
#include "handle.hpp"
#include "pop.hpp"
#include "push.hpp"
namespace wrenbind17 {
class ReturnValue {
public:
ReturnValue() = default;
explicit ReturnValue(const WrenType type, Handle handle) : type(type), handle(std::move(handle)) {
}
~ReturnValue() = default;
ReturnValue(const ReturnValue& other) = delete;
ReturnValue(ReturnValue&& other) noexcept {
swap(other);
}
ReturnValue& operator=(const ReturnValue& other) = delete;
ReturnValue& operator=(ReturnValue&& other) noexcept {
if (this != &other) {
swap(other);
}
return *this;
}
void swap(ReturnValue& other) noexcept {
std::swap(type, other.type);
std::swap(handle, other.handle);
}
const Handle& getHandle() const {
return handle;
}
Handle& getHandle() {
return handle;
}
WrenType getType() const {
return type;
}
template <class T> bool is() const {
if (type == WREN_TYPE_NULL) {
return false;
}
if (const auto vm = handle.getVmWeak().lock()) {
wrenEnsureSlots(vm.get(), 1);
wrenSetSlotHandle(vm.get(), 0, handle.getHandle());
using Type = typename std::remove_reference<typename std::remove_pointer<T>::type>::type;
return detail::is<Type>(vm.get(), 0);
} else {
throw RuntimeError("Invalid handle");
}
}
bool isMap() const {
return type == WREN_TYPE_MAP;
}
bool isList() const {
return type == WREN_TYPE_LIST;
}
template <class T> T as() {
if (type == WREN_TYPE_NULL) {
throw BadCast("Bad cast when getting value from Wren");
}
if (const auto vm = handle.getVmWeak().lock()) {
wrenEnsureSlots(vm.get(), 1);
wrenSetSlotHandle(vm.get(), 0, handle.getHandle());
return detail::PopHelper<T>::f(vm.get(), 0);
} else {
throw RuntimeError("Invalid handle");
}
}
template <class T> std::shared_ptr<T> shared() {
return as<std::shared_ptr<T>>();
}
private:
WrenType type = WrenType::WREN_TYPE_NULL;
Handle handle;
};
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <> inline bool ReturnValue::is<int8_t>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<char>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<short>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<int>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<long>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<long long>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<unsigned char>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<unsigned short>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<unsigned int>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<unsigned long>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<unsigned long long>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<float>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<double>() const {
return type == WREN_TYPE_NUM;
}
template <> inline bool ReturnValue::is<bool>() const {
return type == WREN_TYPE_BOOL;
}
template <> inline bool ReturnValue::is<std::nullptr_t>() const {
return type == WREN_TYPE_NULL;
}
template <> inline bool ReturnValue::is<std::string>() const {
return type == WREN_TYPE_STRING;
}
template <> inline std::nullptr_t ReturnValue::as<std::nullptr_t>() {
if (!is<std::nullptr_t>()) {
throw BadCast("Return value is not a null");
}
return nullptr;
}
#endif
using Any = ReturnValue;
#ifndef DOXYGEN_SHOULD_SKIP_THIS
template <> inline Any detail::getSlot(WrenVM* vm, const int idx) {
const auto type = wrenGetSlotType(vm, 0);
if (type == WREN_TYPE_NULL) {
return Any();
}
return Any(type, Handle(getSharedVm(vm), wrenGetSlotHandle(vm, idx)));
}
#endif
} // namespace wrenbind17
Updated on 17 October 2023 at 12:26:25 UTC