<commit_before>//
// Copyright 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#pragma once

#include <cassert>
#include <exception>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>

#include <jni.h>

// work-around for missing noexcept and constexpr support in MSVC prior to 2015
#if (defined _MSC_VER) && (_MSC_VER < 1900)
#  define noexcept _NOEXCEPT
#  define constexpr
#endif

/*
 * Djinni support library
 */

// jni.h should really put extern "C" in JNIEXPORT, but it doesn't. :(
#define CJNIEXPORT extern "C" JNIEXPORT

namespace djinni {

/*
 * Global initialization and shutdown. Call these from JNI_OnLoad and JNI_OnUnload.
 */
void jniInit(JavaVM * jvm);
void jniShutdown();

/*
 * Get the JNIEnv for the invoking thread. Should only be called on Java-created threads.
 */
JNIEnv * jniGetThreadEnv();

/*
 * Exception to indicate that a Java exception is pending in the JVM.
 */
class jni_exception_pending : public std::exception {};

/*
 * Throw jni_exception_pending if any Java exception is pending in the JVM.
 */
void jniExceptionCheck(JNIEnv * env);
/*
 * Set an AssertionError in env with message message, and then throw jni_exception_pending.
 */
#ifdef _MSC_VER
  __declspec(noreturn)
#else
  __attribute__((noreturn))
#endif
void jniThrowAssertionError(JNIEnv * env, const char * file, int line, const char * check);

#define DJINNI_ASSERT(check, env) \
    do { \
        djinni::jniExceptionCheck(env); \
        const bool check__res = bool(check); \
        djinni::jniExceptionCheck(env); \
        if (!check__res) { \
            djinni::jniThrowAssertionError(env, __FILE__, __LINE__, #check); \
        } \
    } while(false)
/*
 * Global and local reference guard objects.
 *
 * A GlobalRef<T> is constructed with a local reference; the constructor upgrades the local
 * reference to a global reference, and the destructor deletes the local ref.
 *
 * A LocalRef<T> should be constructed with a new local reference. The local reference will
 * be deleted when the LocalRef is deleted.
 */
struct GlobalRefDeleter { void operator() (jobject globalRef) noexcept; };

template <typename PointerType>
class GlobalRef : public std::unique_ptr<typename std::remove_pointer<PointerType>::type,
                                         GlobalRefDeleter> {
public:
    GlobalRef() {}
    GlobalRef(JNIEnv * env, PointerType localRef)
        : std::unique_ptr<typename std::remove_pointer<PointerType>::type, GlobalRefDeleter>(
            static_cast<PointerType>(env->NewGlobalRef(localRef)),
            GlobalRefDeleter{}
        ) {}
};

struct LocalRefDeleter { void operator() (jobject localRef) noexcept; };

template <typename PointerType>
class LocalRef : public std::unique_ptr<typename std::remove_pointer<PointerType>::type,
                                        LocalRefDeleter> {
public:
    LocalRef() {}
    LocalRef(JNIEnv * /*env*/, PointerType localRef)
        : std::unique_ptr<typename std::remove_pointer<PointerType>::type, LocalRefDeleter>(
            localRef) {}
    explicit LocalRef(PointerType localRef)
        : std::unique_ptr<typename std::remove_pointer<PointerType>::type, LocalRefDeleter>(
            localRef) {}
};

/*
 * Helper for JniClassInitializer. Copied from Oxygen.
 */
template <class Key, class T>
class static_registration {
public:
    using registration_map = std::unordered_map<Key, T *>;
    static registration_map get_all() {
        const std::lock_guard<std::mutex> lock(get_mutex());
        return get_map();
    }<commit_msg>Prefix GlobalRefDeleter & LocalRefDeleter with djinni namespace when being used as unique_ptr deleter.<commit_after>//
// Copyright 2014 Dropbox, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

#pragma once

#include <cassert>
#include <exception>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>

#include <jni.h>

// work-around for missing noexcept and constexpr support in MSVC prior to 2015
#if (defined _MSC_VER) && (_MSC_VER < 1900)
#  define noexcept _NOEXCEPT
#  define constexpr
#endif

/*
 * Djinni support library
 */

// jni.h should really put extern "C" in JNIEXPORT, but it doesn't. :(
#define CJNIEXPORT extern "C" JNIEXPORT

namespace djinni {

/*
 * Global initialization and shutdown. Call these from JNI_OnLoad and JNI_OnUnload.
 */
void jniInit(JavaVM * jvm);
void jniShutdown();

/*
 * Get the JNIEnv for the invoking thread. Should only be called on Java-created threads.
 */
JNIEnv * jniGetThreadEnv();

/*
 * Exception to indicate that a Java exception is pending in the JVM.
 */
class jni_exception_pending : public std::exception {};

/*
 * Throw jni_exception_pending if any Java exception is pending in the JVM.
 */
void jniExceptionCheck(JNIEnv * env);
/*
 * Set an AssertionError in env with message message, and then throw jni_exception_pending.
 */
#ifdef _MSC_VER
  __declspec(noreturn)
#else
  __attribute__((noreturn))
#endif
void jniThrowAssertionError(JNIEnv * env, const char * file, int line, const char * check);

#define DJINNI_ASSERT(check, env) \
    do { \
        djinni::jniExceptionCheck(env); \
        const bool check__res = bool(check); \
        djinni::jniExceptionCheck(env); \
        if (!check__res) { \
            djinni::jniThrowAssertionError(env, __FILE__, __LINE__, #check); \
        } \
    } while(false)
/*
 * Global and local reference guard objects.
 *
 * A GlobalRef<T> is constructed with a local reference; the constructor upgrades the local
 * reference to a global reference, and the destructor deletes the local ref.
 *
 * A LocalRef<T> should be constructed with a new local reference. The local reference will
 * be deleted when the LocalRef is deleted.
 */
struct GlobalRefDeleter { void operator() (jobject globalRef) noexcept; };

template <typename PointerType>
class GlobalRef : public std::unique_ptr<typename std::remove_pointer<PointerType>::type,
                                         GlobalRefDeleter> {
public:
    GlobalRef() {}
    GlobalRef(JNIEnv * env, PointerType localRef)
        : std::unique_ptr<typename std::remove_pointer<PointerType>::type, ::djinni::GlobalRefDeleter>(
            static_cast<PointerType>(env->NewGlobalRef(localRef)),
            ::djinni::GlobalRefDeleter{}
        ) {}
};

struct LocalRefDeleter { void operator() (jobject localRef) noexcept; };

template <typename PointerType>
class LocalRef : public std::unique_ptr<typename std::remove_pointer<PointerType>::type,
                                        LocalRefDeleter> {
public:
    LocalRef() {}
    LocalRef(JNIEnv * /*env*/, PointerType localRef)
        : std::unique_ptr<typename std::remove_pointer<PointerType>::type, ::djinni::LocalRefDeleter>(
            localRef) {}
    explicit LocalRef(PointerType localRef)
        : std::unique_ptr<typename std::remove_pointer<PointerType>::type, LocalRefDeleter>(
            localRef) {}
};

/*
 * Helper for JniClassInitializer. Copied from Oxygen.
 */
template <class Key, class T>
class static_registration {
public:
    using registration_map = std::unordered_map<Key, T *>;
    static registration_map get_all() {
        const std::lock_guard<std::mutex> lock(get_mutex());
        return get_map();
    }
{'fraction_non_alphanumeric': 0.10421956232619997, 'fraction_numerical': 0.003868939668722041, 'mean_word_length': 3.5904550499445063, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 55, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5267488', 'n_tokens_mistral': 2436, 'n_tokens_neox': 2385, 'n_words': 787}