#pragma once #include #include #include #include namespace jni { template < class TheTag, class... > class Constructor; template < class TheTag, class > class Field; template < class TheTag, class > class StaticField; template < class TheTag, class > class Method; template < class TheTag, class > class StaticMethod; template < class TheTag > class Class : public Object { public: using TagType = TheTag; using SuperType = Object; using UntaggedType = jclass; protected: explicit Class(std::nullptr_t = nullptr) {} explicit Class(UntaggedType* p) : SuperType(p) {} Class(const Class&) = delete; Class& operator=(const Class&) = delete; public: template < class... ExpectedArgs, class... ActualArgs > auto New(JNIEnv& env, const Constructor& method, const ActualArgs&... args) const -> std::enable_if_t< Conjunction...>::value, Local> > { return Local>(env, &NewObject(env, *this->get(), method, Untag(args)...)); } template < class T > auto Get(JNIEnv& env, const StaticField& field) const -> std::enable_if_t< IsPrimitive::value, T > { return jni::GetStaticField(env, *this->get(), field); } template < class T > auto Get(JNIEnv& env, const StaticField& field) const -> std::enable_if_t< !IsPrimitive::value, Local > { return Local(env, reinterpret_cast(jni::GetStaticField(env, *this->get(), field))); } template < class T > auto Set(JNIEnv& env, const StaticField& field, T value) const -> std::enable_if_t< IsPrimitive::value > { SetStaticField(env, *this->get(), field, value); } template < class Expected, class Actual > auto Set(JNIEnv& env, const StaticField& field, const Actual& value) const -> std::enable_if_t< !IsPrimitive::value && std::is_convertible::value > { SetStaticField(env, *this->get(), field, value.get()); } template < class R, class... ExpectedArgs, class... ActualArgs > auto Call(JNIEnv& env, const StaticMethod& method, const ActualArgs&... args) const -> std::enable_if_t< IsPrimitive::value && Conjunction...>::value, R > { return CallStaticMethod(env, *this->get(), method, Untag(args)...); } template < class R, class... ExpectedArgs, class... ActualArgs > auto Call(JNIEnv& env, const StaticMethod& method, const ActualArgs&... args) const -> std::enable_if_t< !IsPrimitive::value && !std::is_void::value && Conjunction...>::value, Local > { return Local(env, reinterpret_cast(CallStaticMethod(env, *this->get(), method, Untag(args)...))); } template < class... ExpectedArgs, class... ActualArgs > auto Call(JNIEnv& env, const StaticMethod& method, const ActualArgs&... args) const -> std::enable_if_t< Conjunction...>::value > { CallStaticMethod(env, *this->get(), method, Untag(args)...); } static Local Find(JNIEnv& env) { return Local(env, &FindClass(env, TagType::Name())); } static const Class& Singleton(JNIEnv& env) { static Global singleton = NewGlobal(env, Find(env)); return singleton; } template < class... Args > Constructor GetConstructor(JNIEnv& env) const { return Constructor(env, *this); } template < class T > Field GetField(JNIEnv& env, const char* name) const { return Field(env, *this, name); } template < class T > StaticField GetStaticField(JNIEnv& env, const char* name) const { return StaticField(env, *this, name); } template < class T > Method GetMethod(JNIEnv& env, const char* name) const { return Method(env, *this, name); } template < class T > StaticMethod GetStaticMethod(JNIEnv& env, const char* name) const { return StaticMethod(env, *this, name); } }; }