#pragma once #include #include #include #include namespace jni { template < class E, class Enable > class Array; template < class E > class Array< E, std::enable_if_t::value> > : public Object< ArrayTag > { public: using SuperType = Object< ArrayTag >; using UntaggedType = typename SuperType::UntaggedType; using ElementType = E; protected: explicit Array(std::nullptr_t = nullptr) {} explicit Array(UntaggedType* p) : SuperType(p) {} Array(const Array&) = delete; Array& operator=(const Array&) = delete; public: jsize Length(JNIEnv& env) const { return GetArrayLength(env, SafeDereference(env, this->get())); } ElementType Get(JNIEnv& env, jsize index) const { ElementType e; GetArrayRegion(env, SafeDereference(env, this->get()), index, 1, &e); return e; } void Set(JNIEnv& env, jsize index, const ElementType& value) { SetArrayRegion(env, SafeDereference(env, this->get()), index, 1, &value); } template < class Array > void GetRegion(JNIEnv& env, jsize start, Array& buf) const { GetArrayRegion(env, SafeDereference(env, this->get()), start, buf); } template < class Array > void SetRegion(JNIEnv& env, jsize start, const Array& buf) { SetArrayRegion(env, SafeDereference(env, this->get()), start, buf); } static Local> New(JNIEnv& env, jsize length) { return Local>(env, &NewArray(env, length)); } }; template < class TheTag > class Array< Object > : public Object< ArrayTag> > { public: using SuperType = Object< ArrayTag> >; using UntaggedType = typename SuperType::UntaggedType; using TagType = TheTag; using ElementType = Object; using UntaggedElementType = typename ElementType::UntaggedType; protected: explicit Array(std::nullptr_t = nullptr) {} explicit Array(UntaggedType* p) : SuperType(p) {} Array(const Array&) = delete; Array& operator=(const Array&) = delete; public: jsize Length(JNIEnv& env) const { return GetArrayLength(env, SafeDereference(env, this->get())); } Local Get(JNIEnv& env, jsize index) const { return Local(env, reinterpret_cast( GetObjectArrayElement(env, SafeDereference(env, this->get()), index))); } void Set(JNIEnv& env, jsize index, const ElementType& value) { SetObjectArrayElement(env, SafeDereference(env, this->get()), index, Untag(value)); } static Local>> New(JNIEnv& env, jsize length, const Object* initialElement = nullptr) { return Local>>(env, &NewObjectArray(env, length, *Class::Singleton(env), initialElement ? initialElement->get() : nullptr)); } }; template < class T > std::vector MakeAnything(ThingToMake>, JNIEnv& env, const Array& array) { NullCheck(env, array.get()); std::vector result(GetArrayLength(env, *array)); GetArrayRegion(env, *array, 0, result); return result; } template < class T > Local> MakeAnything(ThingToMake>, JNIEnv& env, const std::vector& array) { Local> result = Local>(env, &NewArray(env, array.size())); SetArrayRegion(env, *result, 0, array); return result; } inline std::string MakeAnything(ThingToMake, JNIEnv& env, const Array& array) { NullCheck(env, array.get()); std::string result; result.resize(GetArrayLength(env, *array)); GetArrayRegion(env, *array, 0, result.size(), reinterpret_cast(&result[0])); return result; } inline Local> MakeAnything(ThingToMake>, JNIEnv& env, const std::string& string) { Local> result(env, &NewArray(env, string.size())); SetArrayRegion(env, *result, 0, string.size(), reinterpret_cast(&string[0])); return result; } }