Skip to content

Commit ed7491a

Browse files
committed
Add Box/Unbox
1 parent 5b8d3db commit ed7491a

File tree

2 files changed

+134
-0
lines changed

2 files changed

+134
-0
lines changed

include/jni/boxing.hpp

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
#pragma once
2+
3+
#include <jni/class.hpp>
4+
5+
namespace jni
6+
{
7+
template < class > struct Boxer;
8+
template < class > struct Unboxer;
9+
10+
template < class Unboxed >
11+
auto Box(JNIEnv& env, Unboxed&& unboxed)
12+
{
13+
return Boxer<typename std::decay<Unboxed>::type>().Box(env, std::forward<Unboxed>(unboxed));
14+
}
15+
16+
template < class Tag >
17+
auto Unbox(JNIEnv& env, const Object<Tag>& boxed)
18+
{
19+
return Unboxer<Tag>().Unbox(env, boxed);
20+
}
21+
22+
23+
struct BooleanTag
24+
{
25+
static constexpr auto Name() { return "java/lang/Boolean"; }
26+
static constexpr auto BoxStaticMethodName() { return "valueOf"; }
27+
static constexpr auto UnboxMethodName() { return "booleanValue"; }
28+
};
29+
30+
struct ByteTag
31+
{
32+
static constexpr auto Name() { return "java/lang/Byte"; }
33+
static constexpr auto BoxStaticMethodName() { return "valueOf"; }
34+
static constexpr auto UnboxMethodName() { return "byteValue"; }
35+
};
36+
37+
struct CharacterTag
38+
{
39+
static constexpr auto Name() { return "java/lang/Character"; }
40+
static constexpr auto BoxStaticMethodName() { return "valueOf"; }
41+
static constexpr auto UnboxMethodName() { return "charValue"; }
42+
};
43+
44+
struct ShortTag
45+
{
46+
static constexpr auto Name() { return "java/lang/Short"; }
47+
static constexpr auto BoxStaticMethodName() { return "valueOf"; }
48+
static constexpr auto UnboxMethodName() { return "shortValue"; }
49+
};
50+
51+
struct IntegerTag
52+
{
53+
static constexpr auto Name() { return "java/lang/Integer"; }
54+
static constexpr auto BoxStaticMethodName() { return "valueOf"; }
55+
static constexpr auto UnboxMethodName() { return "intValue"; }
56+
};
57+
58+
struct LongTag
59+
{
60+
static constexpr auto Name() { return "java/lang/Long"; }
61+
static constexpr auto BoxStaticMethodName() { return "valueOf"; }
62+
static constexpr auto UnboxMethodName() { return "longValue"; }
63+
};
64+
65+
struct FloatTag
66+
{
67+
static constexpr auto Name() { return "java/lang/Float"; }
68+
static constexpr auto BoxStaticMethodName() { return "valueOf"; }
69+
static constexpr auto UnboxMethodName() { return "floatValue"; }
70+
};
71+
72+
struct DoubleTag
73+
{
74+
static constexpr auto Name() { return "java/lang/Double"; }
75+
static constexpr auto BoxStaticMethodName() { return "valueOf"; }
76+
static constexpr auto UnboxMethodName() { return "doubleValue"; }
77+
};
78+
79+
80+
template < class Tag, class Unboxed >
81+
struct PrimitiveTypeBoxer
82+
{
83+
Object<Tag> Box(JNIEnv& env, Unboxed unboxed) const
84+
{
85+
static auto klass = Class<Tag>::Singleton(env);
86+
static auto box = klass.template GetStaticMethod<Object<Tag> (Unboxed)>(env, Tag::BoxStaticMethodName());
87+
return klass.Call(env, box, unboxed);
88+
}
89+
};
90+
91+
template <> struct Boxer< jboolean > : PrimitiveTypeBoxer< BooleanTag , jboolean > {};
92+
template <> struct Boxer< jbyte > : PrimitiveTypeBoxer< ByteTag , jbyte > {};
93+
template <> struct Boxer< jchar > : PrimitiveTypeBoxer< CharacterTag , jchar > {};
94+
template <> struct Boxer< jshort > : PrimitiveTypeBoxer< ShortTag , jshort > {};
95+
template <> struct Boxer< jint > : PrimitiveTypeBoxer< IntegerTag , jint > {};
96+
template <> struct Boxer< jlong > : PrimitiveTypeBoxer< LongTag , jlong > {};
97+
template <> struct Boxer< jfloat > : PrimitiveTypeBoxer< FloatTag , jfloat > {};
98+
template <> struct Boxer< jdouble > : PrimitiveTypeBoxer< DoubleTag , jdouble > {};
99+
100+
101+
template < class Tag, class Unboxed >
102+
struct PrimitiveTypeUnboxer
103+
{
104+
Unboxed Unbox(JNIEnv& env, const Object<Tag>& boxed) const
105+
{
106+
static auto klass = Class<Tag>::Singleton(env);
107+
static auto unbox = klass.template GetMethod<Unboxed ()>(env, Tag::UnboxMethodName());
108+
return boxed.Call(env, unbox);
109+
}
110+
};
111+
112+
template <> struct Unboxer< BooleanTag > : PrimitiveTypeUnboxer< BooleanTag , jboolean > {};
113+
template <> struct Unboxer< ByteTag > : PrimitiveTypeUnboxer< ByteTag , jbyte > {};
114+
template <> struct Unboxer< CharacterTag > : PrimitiveTypeUnboxer< CharacterTag , jchar > {};
115+
template <> struct Unboxer< ShortTag > : PrimitiveTypeUnboxer< ShortTag , jshort > {};
116+
template <> struct Unboxer< IntegerTag > : PrimitiveTypeUnboxer< IntegerTag , jint > {};
117+
template <> struct Unboxer< LongTag > : PrimitiveTypeUnboxer< LongTag , jlong > {};
118+
template <> struct Unboxer< FloatTag > : PrimitiveTypeUnboxer< FloatTag , jfloat > {};
119+
template <> struct Unboxer< DoubleTag > : PrimitiveTypeUnboxer< DoubleTag , jdouble > {};
120+
121+
122+
template < class Tag >
123+
struct Boxer<jni::Object<Tag>>
124+
{
125+
const Object<Tag>& Box(JNIEnv&, const jni::Object<Tag>& o) const { return o; }
126+
};
127+
128+
template < class Tag >
129+
struct Unboxer
130+
{
131+
const Object<Tag>& Unbox(JNIEnv&, const jni::Object<Tag>& o) const { return o; }
132+
};
133+
}

include/jni/jni.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,4 @@
1919
#include <jni/field.hpp>
2020
#include <jni/static_field.hpp>
2121
#include <jni/native_method.hpp>
22+
#include <jni/boxing.hpp>

0 commit comments

Comments
 (0)