axmol/thirdparty/jni.hpp/include/jni/wrapping.hpp

153 lines
6.7 KiB
C++

#pragma once
#include <cstddef>
#include <cassert>
#include <limits>
#include <memory>
#include <utility>
#include <jni.h>
namespace jni
{
template < class W > struct Wrapper;
template < class W, class U >
auto Wrap(U&& u)
{
return Wrapper<W>().Wrap(std::forward<U>(u));
}
template < class W >
auto Unwrap(W&& w)
{
return Wrapper<typename std::decay<W>::type>().Unwrap(std::forward<W>(w));
}
template < class T >
using UnwrappedType = decltype(Unwrap<T>(std::declval<T>()));
template < class T >
struct PrimitiveTypeWrapper
{
T Wrap(T t) const { return t; }
T Unwrap(T t) const { return t; }
};
template <> struct Wrapper< jboolean > : PrimitiveTypeWrapper< jboolean > {};
template <> struct Wrapper< jbyte > : PrimitiveTypeWrapper< jbyte > {};
template <> struct Wrapper< jchar > : PrimitiveTypeWrapper< jchar > {};
template <> struct Wrapper< jshort > : PrimitiveTypeWrapper< jshort > {};
template <> struct Wrapper< jint > : PrimitiveTypeWrapper< jint > {};
template <> struct Wrapper< jlong > : PrimitiveTypeWrapper< jlong > {};
template <> struct Wrapper< jfloat > : PrimitiveTypeWrapper< jfloat > {};
template <> struct Wrapper< jdouble > : PrimitiveTypeWrapper< jdouble > {};
template <>
struct Wrapper<const char16_t*>
{
const char16_t* Wrap(const jchar* s) const { return reinterpret_cast<const char16_t*>(s); }
const jchar* Unwrap(const char16_t* s) const { return reinterpret_cast<const jchar*>(s); }
};
template <>
struct Wrapper<char16_t*>
{
char16_t* Wrap(jchar* s) const { return reinterpret_cast<char16_t*>(s); }
jchar* Unwrap(char16_t* s) const { return reinterpret_cast<jchar*>(s); }
};
template <>
struct Wrapper<jsize>
{
jsize Wrap(::jsize s) const
{
if (s < 0)
throw std::range_error("::jsize < 0");
return static_cast<jsize>(s);
}
::jsize Unwrap(jsize s) const
{
if (s > std::numeric_limits<::jsize>::max())
throw std::range_error("jsize > max");
return static_cast<::jsize>(s);
}
};
template < class W, class U >
struct ReferenceTypeWrapper
{
W* Wrap(U u) const { return reinterpret_cast<W*>(u); }
U Unwrap(W* w) const { return reinterpret_cast<U>(w); }
};
template <> struct Wrapper< jobject* > : ReferenceTypeWrapper< jobject, ::jobject > {};
template <> struct Wrapper< jclass* > : ReferenceTypeWrapper< jclass, ::jclass > {};
template <> struct Wrapper< jstring* > : ReferenceTypeWrapper< jstring, ::jstring > {};
template <> struct Wrapper< jthrowable* > : ReferenceTypeWrapper< jthrowable, ::jthrowable > {};
template <> struct Wrapper< jarray< jobject >* > : ReferenceTypeWrapper< jarray< jobject >, ::jobjectArray > {};
template <> struct Wrapper< jarray< jboolean >* > : ReferenceTypeWrapper< jarray< jboolean >, ::jbooleanArray > {};
template <> struct Wrapper< jarray< jbyte >* > : ReferenceTypeWrapper< jarray< jbyte >, ::jbyteArray > {};
template <> struct Wrapper< jarray< jchar >* > : ReferenceTypeWrapper< jarray< jchar >, ::jcharArray > {};
template <> struct Wrapper< jarray< jshort >* > : ReferenceTypeWrapper< jarray< jshort >, ::jshortArray > {};
template <> struct Wrapper< jarray< jint >* > : ReferenceTypeWrapper< jarray< jint >, ::jintArray > {};
template <> struct Wrapper< jarray< jlong >* > : ReferenceTypeWrapper< jarray< jlong >, ::jlongArray > {};
template <> struct Wrapper< jarray< jfloat >* > : ReferenceTypeWrapper< jarray< jfloat >, ::jfloatArray > {};
template <> struct Wrapper< jarray< jdouble >* > : ReferenceTypeWrapper< jarray< jdouble >, ::jdoubleArray > {};
template <> struct Wrapper< jfieldID* > : ReferenceTypeWrapper< jfieldID, ::jfieldID > {};
template <> struct Wrapper< jmethodID* > : ReferenceTypeWrapper< jmethodID, ::jmethodID > {};
// Allow references to be unwrapped to pointers to the underlying type, but not the
// reverse, because dereferences should be explicit, with null checks where necessary.
template < class W, class U >
struct ReferenceTypeUnwrapper
{
U Unwrap(W& w) const { return reinterpret_cast<U>(&w); }
};
template <> struct Wrapper< jobject > : ReferenceTypeUnwrapper< jobject, ::jobject > {};
template <> struct Wrapper< jclass > : ReferenceTypeUnwrapper< jclass, ::jclass > {};
template <> struct Wrapper< jstring > : ReferenceTypeUnwrapper< jstring, ::jstring > {};
template <> struct Wrapper< jthrowable > : ReferenceTypeUnwrapper< jthrowable, ::jthrowable > {};
template <> struct Wrapper< jarray< jobject > > : ReferenceTypeUnwrapper< jarray< jobject >, ::jobjectArray > {};
template <> struct Wrapper< jarray< jboolean > > : ReferenceTypeUnwrapper< jarray< jboolean >, ::jbooleanArray > {};
template <> struct Wrapper< jarray< jbyte > > : ReferenceTypeUnwrapper< jarray< jbyte >, ::jbyteArray > {};
template <> struct Wrapper< jarray< jchar > > : ReferenceTypeUnwrapper< jarray< jchar >, ::jcharArray > {};
template <> struct Wrapper< jarray< jshort > > : ReferenceTypeUnwrapper< jarray< jshort >, ::jshortArray > {};
template <> struct Wrapper< jarray< jint > > : ReferenceTypeUnwrapper< jarray< jint >, ::jintArray > {};
template <> struct Wrapper< jarray< jlong > > : ReferenceTypeUnwrapper< jarray< jlong >, ::jlongArray > {};
template <> struct Wrapper< jarray< jfloat > > : ReferenceTypeUnwrapper< jarray< jfloat >, ::jfloatArray > {};
template <> struct Wrapper< jarray< jdouble > > : ReferenceTypeUnwrapper< jarray< jdouble >, ::jdoubleArray > {};
template <> struct Wrapper< jfieldID > : ReferenceTypeUnwrapper< jfieldID, ::jfieldID > {};
template <> struct Wrapper< jmethodID > : ReferenceTypeUnwrapper< jmethodID, ::jmethodID > {};
template < class T, class R, class... Args >
struct Wrapper< JNINativeMethod< R (JNIEnv*, T*, Args...) > >
{
::JNINativeMethod Unwrap(JNINativeMethod<R (JNIEnv*, T*, Args...)> method) const
{
return { const_cast<char*>(method.name), const_cast<char*>(method.signature), reinterpret_cast<void*>(method.fnPtr) };
}
};
template <>
struct Wrapper<version>
{
version Wrap(::jint v) const { return static_cast<version>(v); }
::jint Unwrap(version v) const { return static_cast<::jint>(v); }
};
}