-
Notifications
You must be signed in to change notification settings - Fork 91
/
class.hpp
137 lines (116 loc) · 5.72 KB
/
class.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#pragma once
#include <jni/functions.hpp>
#include <jni/tagging.hpp>
#include <jni/advanced_ownership.hpp>
#include <jni/object.hpp>
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<ClassTag>
{
public:
using TagType = TheTag;
using SuperType = Object<ClassTag>;
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<TagType, ExpectedArgs...>& method, const ActualArgs&... args) const
-> std::enable_if_t< Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value, Local<Object<TagType>> >
{
return Local<Object<TagType>>(env, &NewObject(env, *this->get(), method, Untag(args)...));
}
template < class T >
auto Get(JNIEnv& env, const StaticField<TagType, T>& field) const
-> std::enable_if_t< IsPrimitive<T>::value, T >
{
return jni::GetStaticField<T>(env, *this->get(), field);
}
template < class T >
auto Get(JNIEnv& env, const StaticField<TagType, T>& field) const
-> std::enable_if_t< !IsPrimitive<T>::value, Local<T> >
{
return Local<T>(env, reinterpret_cast<typename T::UntaggedType*>(jni::GetStaticField<jobject*>(env, *this->get(), field)));
}
template < class T >
auto Set(JNIEnv& env, const StaticField<TagType, T>& field, T value) const
-> std::enable_if_t< IsPrimitive<T>::value >
{
SetStaticField<T>(env, *this->get(), field, value);
}
template < class Expected, class Actual >
auto Set(JNIEnv& env, const StaticField<TagType, Expected>& field, const Actual& value) const
-> std::enable_if_t< !IsPrimitive<Expected>::value
&& std::is_convertible<const Actual&, const Expected&>::value >
{
SetStaticField<jobject*>(env, *this->get(), field, value.get());
}
template < class R, class... ExpectedArgs, class... ActualArgs >
auto Call(JNIEnv& env, const StaticMethod<TagType, R (ExpectedArgs...)>& method, const ActualArgs&... args) const
-> std::enable_if_t< IsPrimitive<R>::value
&& Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value, R >
{
return CallStaticMethod<R>(env, *this->get(), method, Untag(args)...);
}
template < class R, class... ExpectedArgs, class... ActualArgs >
auto Call(JNIEnv& env, const StaticMethod<TagType, R (ExpectedArgs...)>& method, const ActualArgs&... args) const
-> std::enable_if_t< !IsPrimitive<R>::value
&& !std::is_void<R>::value
&& Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value, Local<R> >
{
return Local<R>(env, reinterpret_cast<typename R::UntaggedType*>(CallStaticMethod<jobject*>(env, *this->get(), method, Untag(args)...)));
}
template < class... ExpectedArgs, class... ActualArgs >
auto Call(JNIEnv& env, const StaticMethod<TagType, void (ExpectedArgs...)>& method, const ActualArgs&... args) const
-> std::enable_if_t< Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value >
{
CallStaticMethod<void>(env, *this->get(), method, Untag(args)...);
}
static Local<Class> Find(JNIEnv& env)
{
return Local<Class>(env, &FindClass(env, TagType::Name()));
}
static const Class& Singleton(JNIEnv& env)
{
static Global<Class, EnvIgnoringDeleter> singleton = NewGlobal<EnvIgnoringDeleter>(env, Find(env));
return singleton;
}
template < class... Args >
Constructor<TagType, Args...> GetConstructor(JNIEnv& env) const
{
return Constructor<TagType, Args...>(env, *this);
}
template < class T >
Field<TagType, T> GetField(JNIEnv& env, const char* name) const
{
return Field<TagType, T>(env, *this, name);
}
template < class T >
StaticField<TagType, T> GetStaticField(JNIEnv& env, const char* name) const
{
return StaticField<TagType, T>(env, *this, name);
}
template < class T >
Method<TagType, T> GetMethod(JNIEnv& env, const char* name) const
{
return Method<TagType, T>(env, *this, name);
}
template < class T >
StaticMethod<TagType, T> GetStaticMethod(JNIEnv& env, const char* name) const
{
return StaticMethod<TagType, T>(env, *this, name);
}
};
}