Chromium Code Reviews| Index: webrtc/api/java/jni/jni_helpers.h |
| diff --git a/webrtc/api/java/jni/jni_helpers.h b/webrtc/api/java/jni/jni_helpers.h |
| index 87c5ca48f22e1089bd8cf2ad39468cc17c82e8bb..5ec4d0fee81878bf2a0199bd09af7622840cf7d2 100644 |
| --- a/webrtc/api/java/jni/jni_helpers.h |
| +++ b/webrtc/api/java/jni/jni_helpers.h |
| @@ -17,6 +17,7 @@ |
| #include <jni.h> |
| #include <string> |
| +#include "webrtc/base/constructormagic.h" |
| #include "webrtc/base/checks.h" |
| // Abort the process if |jni| has a Java exception pending. |
| @@ -122,6 +123,62 @@ class ScopedGlobalRef { |
| T obj_; |
| }; |
| +// Provides a convenient way to iterate over a Java Iterable using the |
| +// C++ range-for loop. |
| +// E.g. for (jobject value : Iterable(jni, j_iterable)) { ... } |
| +// Note: Since Java iterators cannot be duplicated, this class is not copyable |
| +// to prevent creating multiple C++ iterators that refer to the same Java |
| +// iterator. |
| +class Iterator { |
|
magjed_webrtc
2016/03/22 15:15:30
Maybe this should be a nested class in Iterable in
skvlad
2016/03/23 00:29:27
Done.
|
| + public: |
| + // Creates an iterator representing the end of any collection. |
| + Iterator(); |
| + // Creates an iterator pointing to the beginning of the specified collection. |
| + Iterator(JNIEnv* jni, jobject iterable); |
| + |
| + // Move constructor - necessary to be able to return iterator types from |
| + // functions. |
| + Iterator(Iterator&& other); |
| + |
| + // Move assignment should not be used. |
| + Iterator& operator=(Iterator&&) = delete; |
| + |
| + // Advances the iterator one step. |
| + Iterator& operator++(); |
| + |
| + bool operator==(const Iterator& other) { |
| + return (iterator_ == other.iterator_); |
|
magjed_webrtc
2016/03/22 15:15:30
This looks a bit hacky, because you can't compare
skvlad
2016/03/23 00:29:27
This would make two iterators pointing to the same
magjed_webrtc
2016/03/23 14:51:25
This is good, thanks for the detailed explanation!
|
| + } |
| + bool operator!=(const Iterator& other) { return !(*this == other); } |
| + |
| + jobject operator*() { return value_; } |
| + |
| + private: |
| + JNIEnv* jni_ = NULL; |
| + jobject iterator_ = NULL; |
| + jobject value_ = NULL; |
| + jmethodID has_next_id_ = NULL; |
| + jmethodID next_id_ = NULL; |
| + |
| + RTC_DISALLOW_COPY_AND_ASSIGN(Iterator); |
| +}; |
| + |
| +class Iterable { |
| + public: |
| + explicit Iterable(JNIEnv* jni, jobject iterable) |
|
magjed_webrtc
2016/03/22 15:15:30
Why explicit if you have two arguments?
skvlad
2016/03/23 00:29:27
Oops, my mistake. It used to have one in the previ
|
| + : jni_(jni), iterable_(iterable) {} |
|
magjed_webrtc
2016/03/22 15:15:30
If you store JNIEnv, I would like to have a thread
skvlad
2016/03/23 00:29:27
Done.
|
| + |
| + Iterator begin() { return Iterator(jni_, iterable_); } |
| + |
| + Iterator end() { return Iterator(); } |
| + |
| + private: |
| + JNIEnv* jni_; |
| + jobject iterable_; |
| + |
| + RTC_DISALLOW_COPY_AND_ASSIGN(Iterable); |
| +}; |
| + |
| } // namespace webrtc_jni |
| #endif // WEBRTC_API_JAVA_JNI_JNI_HELPERS_H_ |