-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnostringmaps.h
94 lines (76 loc) · 3.35 KB
/
nostringmaps.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#pragma once
#include <notypes.h>
namespace Nobind {
namespace Typemap {
template <typename T> class FromJSString {
std::remove_cv_t<std::remove_reference_t<T>> val_;
public:
inline explicit FromJSString(const Napi::Value &val) {
if (!val.IsString()) {
throw Napi::TypeError::New(val.Env(), "Expected a string");
}
val_ = val.ToString().Utf8Value();
}
inline T Get() { return val_; }
FromJSString(const FromJSString &) = delete;
FromJSString(FromJSString &&) = default;
};
template <typename T, const ReturnAttribute &RETATTR> class ToJSString {
Napi::Env env_;
T val_;
public:
inline explicit ToJSString(Napi::Env env, T val) : env_(env), val_(val) {}
inline Napi::Value Get() { return Napi::String::New(env_, val_); }
ToJSString(const ToJSString &) = delete;
ToJSString(ToJSString &&) = default;
};
template <typename T> class FromJSChar {
char *val_;
public:
inline explicit FromJSChar(const Napi::Value &val) {
if (!val.IsString()) {
throw Napi::TypeError::New(val.Env(), "Expected a string");
}
std::string s = val.ToString().Utf8Value();
val_ = new char[s.size() + 1];
strncpy(val_, s.c_str(), s.size());
val_[s.size()] = 0;
}
inline T Get() { return val_; }
~FromJSChar() { delete val_; }
FromJSChar(const FromJSChar &) = delete;
FromJSChar(FromJSChar &&) = default;
};
template <typename T, const ReturnAttribute &RETATTR> class ToJSChar {
Napi::Env env_;
T val_;
public:
inline explicit ToJSChar(Napi::Env env, T val) : env_(env), val_(val) {}
inline Napi::Value Get() { return Napi::String::New(env_, val_); }
ToJSChar(const ToJSChar &) = delete;
ToJSChar(ToJSChar &&) = default;
};
const std::string string_tstype = "string"s;
#define TYPEMAPS_FOR_STRING(TYPE, CLASS) \
template <> struct FromJS<TYPE> : public FromJS##CLASS<TYPE> { \
using FromJS##CLASS<TYPE>::FromJS##CLASS; \
static const std::string &TSType() { return string_tstype; }; \
}; \
template <const ReturnAttribute &RETATTR> struct ToJS<TYPE, RETATTR> : public ToJS##CLASS<TYPE, RETATTR> { \
using ToJS##CLASS<TYPE, RETATTR>::ToJS##CLASS; \
static const std::string &TSType() { return string_tstype; }; \
};
// The const versions are needed to ensure that we
// do not end up using the T& specialization (ie we are always more specialized)
TYPEMAPS_FOR_STRING(std::string, String);
TYPEMAPS_FOR_STRING(const std::string, String);
TYPEMAPS_FOR_STRING(std::string &, String);
TYPEMAPS_FOR_STRING(const std::string &, String);
// remove_const_t<const char*> == const char* (it is a pointer before being a const)
// remove_const_t<char const*> == char* (but few people use this notation)
// remove_pointer_t<const char*> == const char
// remove_const_t<remove_pointer_t<const char *>> == char
TYPEMAPS_FOR_STRING(char *, Char);
TYPEMAPS_FOR_STRING(const char *, Char);
} // namespace Typemap
} // namespace Nobind