external/jnipp: Move away from explicit instantiation of function templates.

Makes it too hard to track down errors: they showed up as linker errors, instead of compiler errors.
This commit is contained in:
Ryan Pavlik 2021-04-30 17:55:34 -05:00
parent 4ef5b65487
commit bc4cf1cb93
2 changed files with 62 additions and 27 deletions

View file

@ -353,20 +353,20 @@ namespace jni
return _handle == nullptr || env()->IsSameObject(_handle, nullptr);
}
template <> void Object::callMethod(method_t method, internal::value_t* args) const
void Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<void> const&) const
{
env()->CallVoidMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
}
template <> bool Object::callMethod(method_t method, internal::value_t* args) const
bool Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<bool> const&) const
{
auto result = env()->CallBooleanMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return result != 0;
}
template <> bool Object::get(field_t field) const
bool Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<bool> const&) const
{
return env()->GetBooleanField(_handle, field) != 0;
}
@ -376,122 +376,122 @@ namespace jni
env()->SetBooleanField(_handle, field, value);
}
template <> byte_t Object::callMethod(method_t method, internal::value_t* args) const
byte_t Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<byte_t> const&) const
{
auto result = env()->CallByteMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return result;
}
template <> wchar_t Object::callMethod(method_t method, internal::value_t* args) const
wchar_t Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<wchar_t> const&) const
{
auto result = env()->CallCharMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return result;
}
template <> short Object::callMethod(method_t method, internal::value_t* args) const
short Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<short> const&) const
{
auto result = env()->CallShortMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return result;
}
template <> int Object::callMethod(method_t method, internal::value_t* args) const
int Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<int> const&) const
{
auto result = env()->CallIntMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return result;
}
template <> long long Object::callMethod(method_t method, internal::value_t* args) const
long long Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<long long> const&) const
{
auto result = env()->CallLongMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return result;
}
template <> float Object::callMethod(method_t method, internal::value_t* args) const
float Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<float> const&) const
{
auto result = env()->CallFloatMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return result;
}
template <> double Object::callMethod(method_t method, internal::value_t* args) const
double Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<double> const&) const
{
auto result = env()->CallDoubleMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return result;
}
template <> std::string Object::callMethod(method_t method, internal::value_t* args) const
std::string Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<std::string> const&) const
{
auto result = env()->CallObjectMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return toString(result);
}
template <> std::wstring Object::callMethod(method_t method, internal::value_t* args) const
std::wstring Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<std::wstring> const&) const
{
auto result = env()->CallObjectMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return toWString(result);
}
template <> jni::Object Object::callMethod(method_t method, internal::value_t* args) const
jni::Object Object::callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<jni::Object> const&) const
{
auto result = env()->CallObjectMethodA(_handle, method, (jvalue*) args);
handleJavaExceptions();
return Object(result, DeleteLocalInput);
}
template <> byte_t Object::get(field_t field) const
byte_t Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<byte_t> const&) const
{
return env()->GetByteField(_handle, field);
}
template <> wchar_t Object::get(field_t field) const
wchar_t Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<wchar_t> const&) const
{
return env()->GetCharField(_handle, field);
}
template <> short Object::get(field_t field) const
short Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<short> const&) const
{
return env()->GetShortField(_handle, field);
}
template <> int Object::get(field_t field) const
int Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<int> const&) const
{
return env()->GetIntField(_handle, field);
}
template <> long long Object::get(field_t field) const
long long Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<long long> const&) const
{
return env()->GetLongField(_handle, field);
}
template <> float Object::get(field_t field) const
float Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<float> const&) const
{
return env()->GetFloatField(_handle, field);
}
template <> double Object::get(field_t field) const
double Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<double> const&) const
{
return env()->GetDoubleField(_handle, field);
}
template <> std::string Object::get(field_t field) const
std::string Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<std::string> const&) const
{
return toString(env()->GetObjectField(_handle, field));
}
template <> std::wstring Object::get(field_t field) const
std::wstring Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<std::wstring> const&) const
{
return toWString(env()->GetObjectField(_handle, field));
}
template <> Object Object::get(field_t field) const
Object Object::getFieldValue(field_t field, internal::ReturnTypeWrapper<Object> const&) const
{
return Object(env()->GetObjectField(_handle, field), DeleteLocalInput);
}

View file

@ -176,6 +176,11 @@ namespace jni
};
long getArrayLength(jarray array);
template<typename T>
struct ReturnTypeWrapper{
using type = T;
};
}
/**
@ -282,7 +287,7 @@ namespace jni
\return The method's return value.
*/
template <class TReturn>
TReturn call(method_t method) const { return callMethod<TReturn>(method, nullptr); }
TReturn call(method_t method) const { return callMethod(method, nullptr, internal::ReturnTypeWrapper<TReturn>{}); }
/**
Calls the method on this Object with the given name, and no arguments.
@ -312,7 +317,7 @@ namespace jni
template <class TReturn, class... TArgs>
TReturn call(method_t method, const TArgs&... args) const {
internal::ArgArray<TArgs...> transform(args...);
return callMethod<TReturn>(method, transform.values);
return callMethod(method, transform.values, internal::ReturnTypeWrapper<TReturn>{});
}
/**
@ -342,7 +347,11 @@ namespace jni
\return The field's value.
*/
template <class TType>
TType get(field_t field) const;
TType get(field_t field) const {
// If you get a compile error here, then you've asked for a type
// we don't know how to get from JNI directly.
return getFieldValue(field, internal::ReturnTypeWrapper<TType>{});
}
/**
Gets a field value from this Object. The field must belong to the
@ -410,7 +419,33 @@ namespace jni
method_t getMethod(const char* name, const char* signature) const;
method_t getMethod(const char* nameAndSignature) const;
field_t getField(const char* name, const char* signature) const;
template <class TType> TType callMethod(method_t method, internal::value_t* values) const;
void callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<void> const&) const;
bool callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<bool> const&) const;
byte_t callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<byte_t> const&) const;
wchar_t callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<wchar_t> const&) const;
short callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<short> const&) const;
int callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<int> const&) const;
long long callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<long long> const&) const;
float callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<float> const&) const;
double callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<double> const&) const;
std::string callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<std::string> const&) const;
std::wstring callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<std::wstring> const&) const;
jni::Object callMethod(method_t method, internal::value_t* args, internal::ReturnTypeWrapper<jni::Object> const&) const;
void getFieldValue(field_t field, internal::ReturnTypeWrapper<void> const&) const;
bool getFieldValue(field_t field, internal::ReturnTypeWrapper<bool> const&) const;
byte_t getFieldValue(field_t field, internal::ReturnTypeWrapper<byte_t> const&) const;
wchar_t getFieldValue(field_t field, internal::ReturnTypeWrapper<wchar_t> const&) const;
short getFieldValue(field_t field, internal::ReturnTypeWrapper<short> const&) const;
int getFieldValue(field_t field, internal::ReturnTypeWrapper<int> const&) const;
long long getFieldValue(field_t field, internal::ReturnTypeWrapper<long long> const&) const;
float getFieldValue(field_t field, internal::ReturnTypeWrapper<float> const&) const;
double getFieldValue(field_t field, internal::ReturnTypeWrapper<double> const&) const;
std::string getFieldValue(field_t field, internal::ReturnTypeWrapper<std::string> const&) const;
std::wstring getFieldValue(field_t field, internal::ReturnTypeWrapper<std::wstring> const&) const;
jni::Object getFieldValue(field_t field, internal::ReturnTypeWrapper<jni::Object> const&) const;
// Instance Variables
jobject _handle;