lime
Lime is a C++ library implementing Open Whisper System Signal protocol
object.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <jni/functions.hpp>
4 #include <jni/tagging.hpp>
5 
6 #include <cstddef>
7 
8 namespace jni
9  {
10  template < class TheTag > class Class;
11  template < class TheTag, class > class Field;
12  template < class TheTag, class > class Method;
13 
14  class ObjectBase
15  {
16  protected:
17  jobject* ptr = nullptr;
18 
19  explicit ObjectBase(std::nullptr_t = nullptr)
20  {}
21 
22  explicit ObjectBase(jobject* p)
23  : ptr(p)
24  {}
25 
26  ~ObjectBase() = default;
27 
28  void reset(jobject* p) { ptr = p; }
29 
30  public:
31  explicit operator bool() const { return ptr; }
32 
33  friend bool operator==(const ObjectBase& a, const ObjectBase& b) { return a.ptr == b.ptr; }
34  friend bool operator!=(const ObjectBase& a, const ObjectBase& b) { return !( a == b ); }
35 
36  template < class OtherTag >
37  bool IsInstanceOf(JNIEnv& env, const Class<OtherTag>& clazz) const
38  {
39  return jni::IsInstanceOf(env, ptr, *clazz);
40  }
41  };
42 
43  template < class TheTag = ObjectTag >
44  class Object : public TagTraits<TheTag>::SuperType
45  {
46  public:
47  using TagType = TheTag;
50 
51  protected:
52  explicit Object(std::nullptr_t = nullptr)
53  {}
54 
55  explicit Object(UntaggedType* p)
56  : SuperType(p)
57  {}
58 
59  Object(const Object&) = delete;
60  Object& operator=(const Object&) = delete;
61 
62  public:
63  UntaggedType* get() const { return reinterpret_cast<UntaggedType*>(this->ptr); }
64  UntaggedType& operator*() const { return *get(); }
65 
66  template < class T >
67  auto Get(JNIEnv& env, const Field<TagType, T>& field) const
68  -> std::enable_if_t< IsPrimitive<T>::value, T >
69  {
70  return GetField<T>(env, get(), field);
71  }
72 
73  template < class T >
74  auto Get(JNIEnv& env, const Field<TagType, T>& field) const
75  -> std::enable_if_t< !IsPrimitive<T>::value, Local<T> >
76  {
77  return Local<T>(env, reinterpret_cast<typename T::UntaggedType*>(GetField<jobject*>(env, get(), field)));
78  }
79 
80  template < class T >
81  auto Set(JNIEnv& env, const Field<TagType, T>& field, T value) const
82  -> std::enable_if_t< IsPrimitive<T>::value >
83  {
84  SetField<T>(env, get(), field, value);
85  }
86 
87  template < class Expected, class Actual >
88  auto Set(JNIEnv& env, const Field<TagType, Expected>& field, const Actual& value) const
89  -> std::enable_if_t< !IsPrimitive<Expected>::value
90  && std::is_convertible<const Actual&, const Expected&>::value >
91  {
92  SetField<jobject*>(env, get(), field, value.get());
93  }
94 
95  template < class R, class... ExpectedArgs, class... ActualArgs >
96  auto Call(JNIEnv& env, const Method<TagType, R (ExpectedArgs...)>& method, const ActualArgs&... args) const
97  -> std::enable_if_t< IsPrimitive<R>::value
99  {
100  return CallMethod<R>(env, get(), method, Untag(args)...);
101  }
102 
103  template < class R, class... ExpectedArgs, class... ActualArgs >
104  auto Call(JNIEnv& env, const Method<TagType, R (ExpectedArgs...)>& method, const ActualArgs&... args) const
105  -> std::enable_if_t< !IsPrimitive<R>::value
106  && !std::is_void<R>::value
108  {
109  return Local<R>(env, reinterpret_cast<typename R::UntaggedType*>(CallMethod<jobject*>(env, get(), method, Untag(args)...)));
110  }
111 
112  template < class... ExpectedArgs, class... ActualArgs >
113  auto Call(JNIEnv& env, const Method<TagType, void (ExpectedArgs...)>& method, const ActualArgs&... args) const
114  -> std::enable_if_t< Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value >
115  {
116  CallMethod<void>(env, get(), method, Untag(args)...);
117  }
118 
119  template < class R, class... ExpectedArgs, class... ActualArgs >
120  auto CallNonvirtual(JNIEnv& env, const Class<TagType>& clazz, const Method<TagType, R (ExpectedArgs...)>& method, const ActualArgs&... args) const
121  -> std::enable_if_t< IsPrimitive<R>::value
123  {
124  return CallNonvirtualMethod<R>(env, get(), clazz, method, Untag(args)...);
125  }
126 
127  template < class R, class... ExpectedArgs, class... ActualArgs >
128  auto CallNonvirtual(JNIEnv& env, const Class<TagType>& clazz, const Method<TagType, R (ExpectedArgs...)>& method, const ActualArgs&... args) const
129  -> std::enable_if_t< !IsPrimitive<R>::value
130  && !std::is_void<R>::value
132  {
133  return Local<R>(env, reinterpret_cast<typename R::UntaggedType*>(CallNonvirtualMethod<jobject*>(env, get(), clazz, method, Untag(args)...)));
134  }
135 
136  template < class... ExpectedArgs, class... ActualArgs >
137  auto CallNonvirtual(JNIEnv& env, const Class<TagType>& clazz, const Method<TagType, void (ExpectedArgs...)>& method, const ActualArgs&... args) const
138  -> std::enable_if_t< Conjunction<std::is_convertible<const ActualArgs&, const ExpectedArgs&>...>::value >
139  {
140  CallNonvirtualMethod<void>(env, get(), clazz, method, Untag(args)...);
141  }
142  };
143 
144  template < class OutTagType, class T >
145  Local<Object<OutTagType>> Cast(JNIEnv& env, const Class<OutTagType>& clazz, const T& object)
146  {
147  if (!object.IsInstanceOf(env, clazz))
148  {
149  ThrowNew(env, FindClass(env, "java/lang/ClassCastException"));
150  }
151  return Local<Object<OutTagType>>(env, reinterpret_cast<typename Object<OutTagType>::UntaggedType*>(NewLocal(env, object).release()));
152  }
153  }
decltype(Untag(std::declval< T >())) UntaggedType
Definition: tagging.hpp:130
auto Set(JNIEnv &env, const Field< TagType, Expected > &field, const Actual &value) const -> std::enable_if_t< !IsPrimitive< Expected >::value &&std::is_convertible< const Actual &, const Expected &>::value >
Definition: object.hpp:88
auto Call(JNIEnv &env, const Method< 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 >
Definition: object.hpp:96
~ObjectBase()=default
bool IsInstanceOf(JNIEnv &env, const Class< OtherTag > &clazz) const
Definition: object.hpp:37
ObjectBase(jobject *p)
Definition: object.hpp:22
void ThrowNew(JNIEnv &env, jclass &clazz, const char *msg=nullptr)
Definition: functions.hpp:84
ObjectBase(std::nullptr_t=nullptr)
Definition: object.hpp:19
jobject * ptr
Definition: object.hpp:17
void reset(jobject *p)
Definition: object.hpp:28
Definition: object.hpp:44
Definition: object.hpp:14
Definition: tagging.hpp:51
Definition: advanced_ownership.hpp:5
bool IsInstanceOf(JNIEnv &env, jobject *obj, jclass &clazz)
Definition: functions.hpp:253
auto Get(JNIEnv &env, const Field< TagType, T > &field) const -> std::enable_if_t< IsPrimitive< T >::value, T >
Definition: object.hpp:67
auto CallNonvirtual(JNIEnv &env, const Class< TagType > &clazz, const Method< TagType, void(ExpectedArgs...)> &method, const ActualArgs &... args) const -> std::enable_if_t< Conjunction< std::is_convertible< const ActualArgs &, const ExpectedArgs &>... >::value >
Definition: object.hpp:137
Object(std::nullptr_t=nullptr)
Definition: object.hpp:52
friend bool operator!=(const ObjectBase &a, const ObjectBase &b)
Definition: object.hpp:34
Local< Object< OutTagType > > Cast(JNIEnv &env, const Class< OutTagType > &clazz, const T &object)
Definition: object.hpp:145
UntaggedType & operator*() const
Definition: object.hpp:64
auto Untag(T primitive) -> std::enable_if_t< IsPrimitive< T >::value, T >
Definition: tagging.hpp:116
Definition: class.hpp:17
Definition: unique.hpp:38
Definition: class.hpp:13
auto Set(JNIEnv &env, const Field< TagType, T > &field, T value) const -> std::enable_if_t< IsPrimitive< T >::value >
Definition: object.hpp:81
auto Call(JNIEnv &env, const Method< 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 > >
Definition: object.hpp:104
auto CallNonvirtual(JNIEnv &env, const Class< TagType > &clazz, const Method< 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 > >
Definition: object.hpp:128
Definition: class.hpp:11
jclass & FindClass(JNIEnv &env, const char *name)
Definition: functions.hpp:34
auto NewLocal(JNIEnv &env, const T &t)
Definition: unique.hpp:202
TheTag TagType
Definition: object.hpp:47
typename TagTraits< TheTag >::SuperType SuperType
Definition: object.hpp:48
auto Get(JNIEnv &env, const Field< TagType, T > &field) const -> std::enable_if_t< !IsPrimitive< T >::value, Local< T > >
Definition: object.hpp:74
auto CallNonvirtual(JNIEnv &env, const Class< TagType > &clazz, const Method< 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 >
Definition: object.hpp:120
typename TagTraits< TheTag >::UntaggedType UntaggedType
Definition: object.hpp:49
Definition: traits.hpp:28
Object(UntaggedType *p)
Definition: object.hpp:55
friend bool operator==(const ObjectBase &a, const ObjectBase &b)
Definition: object.hpp:33
auto Call(JNIEnv &env, const Method< TagType, void(ExpectedArgs...)> &method, const ActualArgs &... args) const -> std::enable_if_t< Conjunction< std::is_convertible< const ActualArgs &, const ExpectedArgs &>... >::value >
Definition: object.hpp:113
Definition: types.hpp:30