C++ Essence Library 0.1.0
A Utility Library for Modern C++ Programming
Loading...
Searching...
No Matches
reflector.hpp
1/*
2 * Copyright (c) 2024 The RefValue Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include "../compat.hpp"
26#include "../zstring_view.hpp"
27#include "global_ref.hpp"
28
29#include <concepts>
30#include <cstddef>
31#include <cstdint>
32#include <memory>
33#include <tuple>
34#include <type_traits>
35#include <utility>
36
37#include <jni.h>
38
39namespace essence::jni::detail {
40 template <typename T>
41 struct is_enum_tuple : std::false_type {};
42
43 template <typename T, typename... Args>
44 requires(std::is_enum_v<T> || std::integral<T>)
45 struct is_enum_tuple<std::tuple<T, Args...>> : std::true_type {};
46
47 template <typename T>
48 concept enum_tuple = is_enum_tuple<std::decay_t<T>>::value;
49
50 template <enum_tuple Tuple>
51 constexpr auto from_enum_tuple(const Tuple& source) {
52 return [&]<std::size_t... Is>(std::index_sequence<Is...>) {
53 return std::tuple{static_cast<std::int32_t>(std::get<0>(source)), std::get<(Is + 1)>(source)...};
54 }(std::make_index_sequence<std::tuple_size_v<Tuple> - 1>{});
55 }
56} // namespace essence::jni::detail
57
58namespace essence::jni {
59 class reflector {
60 public:
61 using tuple_type = std::tuple<std::int32_t, zstring_view, zstring_view>;
62
63 ES_API(JNISUPPORT) reflector(reflector&&) noexcept;
64 ES_API(JNISUPPORT) ~reflector();
65 ES_API(JNISUPPORT) reflector& operator=(reflector&&) noexcept;
66 ES_API(JNISUPPORT) static const reflector& instance();
67 [[nodiscard]] ES_API(JNISUPPORT) global_ref_ex<jclass> get_class(std::int32_t key) const;
68 [[nodiscard]] ES_API(JNISUPPORT) jfieldID get_field(std::int32_t key) const;
69 [[nodiscard]] ES_API(JNISUPPORT) jmethodID get_method(std::int32_t key) const;
70 [[nodiscard]] ES_API(JNISUPPORT) global_ref_ex<jclass> add_class(std::int32_t key, zstring_view name) const;
71 [[nodiscard]] ES_API(JNISUPPORT) jfieldID add_field(std::int32_t class_key, const tuple_type& field) const;
72 [[nodiscard]] ES_API(JNISUPPORT) jmethodID add_method(std::int32_t class_key, const tuple_type& method) const;
73 [[nodiscard]] ES_API(JNISUPPORT) jfieldID
74 add_static_field(std::int32_t class_key, const tuple_type& field) const;
75 [[nodiscard]] ES_API(JNISUPPORT) jmethodID
76 add_static_method(std::int32_t class_key, const tuple_type& method) const;
77 ES_API(JNISUPPORT) void clear() const;
78
79 template <typename T, detail::enum_tuple Tuple>
80 requires std::is_enum_v<T>
81 jfieldID add_field(T class_key, const Tuple& field) const {
82 return add_field(static_cast<std::int32_t>(class_key), detail::from_enum_tuple(field));
83 }
84
85 template <typename T, detail::enum_tuple Tuple>
86 requires std::is_enum_v<T>
87 jmethodID add_method(T class_key, const Tuple& method) const {
88 return add_method(static_cast<std::int32_t>(class_key), detail::from_enum_tuple(method));
89 }
90
91 template <typename T, detail::enum_tuple Tuple>
92 requires std::is_enum_v<T>
93 jfieldID add_static_field(T class_key, const Tuple& field) const {
94 return add_static_field(static_cast<std::int32_t>(class_key), detail::from_enum_tuple(field));
95 }
96
97 template <typename T, detail::enum_tuple Tuple>
98 requires std::is_enum_v<T>
99 jmethodID add_static_method(T class_key, const Tuple& method) const {
100 return add_static_method(static_cast<std::int32_t>(class_key), detail::from_enum_tuple(method));
101 }
102
103 template <typename T, detail::enum_tuple... Args>
104 requires(std::is_enum_v<T> || std::integral<T>)
105 auto add_fields(T class_key, Args&&... fields) const {
106 return std::tuple{add_field(class_key, std::forward<Args>(fields))...};
107 }
108
109 template <typename T, detail::enum_tuple... Args>
110 requires(std::is_enum_v<T> || std::integral<T>)
111 auto add_methods(T class_key, Args&&... methods) const {
112 return std::tuple{add_method(class_key, std::forward<Args>(methods))...};
113 }
114
115 template <typename T, detail::enum_tuple... Args>
116 requires(std::is_enum_v<T> || std::integral<T>)
117 auto add_static_fields(T class_key, Args&&... fields) const {
118 return std::tuple{add_static_field(class_key, std::forward<Args>(fields))...};
119 }
120
121 template <typename T, detail::enum_tuple... Args>
122 requires(std::is_enum_v<T> || std::integral<T>)
123 auto add_static_methods(T class_key, Args&&... methods) const {
124 return std::tuple{add_static_method(class_key, std::forward<Args>(methods))...};
125 }
126
127 private:
128 reflector();
129
130 class impl;
131
132 std::unique_ptr<impl> impl_;
133 };
134} // namespace essence::jni
Definition zstring_view.hpp:34
Definition global_ref.hpp:57
Definition reflector.hpp:59
Definition reflector.hpp:48
Definition reflector.hpp:41