From 93333fe52b0d8aaf10314a89a4c04d64debc7382 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Fri, 30 Jan 2026 18:22:49 +0100 Subject: [PATCH 1/4] Add String::New overload for string_view --- napi-inl.h | 9 +++++++++ napi.h | 11 +++++++++++ 2 files changed, 20 insertions(+) diff --git a/napi-inl.h b/napi-inl.h index 0f1717ecd..8e05bbcce 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -20,6 +20,9 @@ #endif // NAPI_HAS_THREADS #include #include +#if __cplusplus >= 201703L +#include +#endif #if defined(__clang__) || defined(__GNUC__) #define NAPI_NO_SANITIZE_VPTR __attribute__((no_sanitize("vptr"))) @@ -1255,6 +1258,12 @@ inline String String::New(napi_env env, const std::u16string& val) { return String::New(env, val.c_str(), val.size()); } +#if __cplusplus >= 201703L +inline String String::New(napi_env env, const std::string_view& val) { + return String::New(env, val.data(), val.size()); +} +#endif + inline String String::New(napi_env env, const char* val) { // TODO(@gabrielschulhof) Remove if-statement when core's error handling is // available in all supported versions. diff --git a/napi.h b/napi.h index 013a9114d..c6e925d1d 100644 --- a/napi.h +++ b/napi.h @@ -19,6 +19,9 @@ #endif // NAPI_HAS_THREADS #include #include +#if __cplusplus >= 201703L +#include +#endif // VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known // good version) @@ -718,6 +721,14 @@ class String : public Name { const std::u16string& value ///< UTF-16 encoded C++ string ); +#if __cplusplus >= 201703L + /// Creates a new String value from a UTF-8 encoded C++ string view. + static String New( + napi_env env, ///< Node-API environment + const std::string_view& value ///< UTF-8 encoded C++ string view + ); +#endif + /// Creates a new String value from a UTF-8 encoded C string. static String New( napi_env env, ///< Node-API environment From 5b7448e8b2e109bb9bda5cd19d9f6c3bca14b35d Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Fri, 30 Jan 2026 19:42:56 +0100 Subject: [PATCH 2/4] Add Symbol::New with string_view --- napi-inl.h | 9 ++++++++- napi.h | 14 +++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/napi-inl.h b/napi-inl.h index 8e05bbcce..b7cf63c1b 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -1259,7 +1259,7 @@ inline String String::New(napi_env env, const std::u16string& val) { } #if __cplusplus >= 201703L -inline String String::New(napi_env env, const std::string_view& val) { +inline String String::New(napi_env env, std::string_view val) { return String::New(env, val.data(), val.size()); } #endif @@ -1373,6 +1373,13 @@ inline Symbol Symbol::New(napi_env env, const std::string& description) { return Symbol::New(env, descriptionValue); } +#if __cplusplus >= 201703L +inline Symbol Symbol::New(napi_env env, std::string_view description) { + napi_value descriptionValue = String::New(env, description); + return Symbol::New(env, descriptionValue); +} +#endif + inline Symbol Symbol::New(napi_env env, String description) { napi_value descriptionValue = description; return Symbol::New(env, descriptionValue); diff --git a/napi.h b/napi.h index c6e925d1d..d9c4c4add 100644 --- a/napi.h +++ b/napi.h @@ -723,9 +723,8 @@ class String : public Name { #if __cplusplus >= 201703L /// Creates a new String value from a UTF-8 encoded C++ string view. - static String New( - napi_env env, ///< Node-API environment - const std::string_view& value ///< UTF-8 encoded C++ string view + static String New(napi_env env, ///< Node-API environment + std::string_view value ///< UTF-8 encoded C++ string view ); #endif @@ -802,6 +801,15 @@ class Symbol : public Name { description ///< UTF-8 encoded C++ string describing the symbol ); +#if __cplusplus >= 201703L + /// Creates a new Symbol value with a description. + static Symbol New( + napi_env env, ///< Node-API environment + std::string_view + description ///< UTF-8 encoded C++ string view describing the symbol + ); +#endif + /// Creates a new Symbol value with a description. static Symbol New(napi_env env, ///< Node-API environment String description ///< String value describing the symbol From 9deb2e22b95fa29d1815b65d5eb5816b125d9ab2 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Tue, 3 Feb 2026 11:07:21 +0100 Subject: [PATCH 3/4] Add String/Symbol::New with string view unit tests --- napi-inl.h | 8 +------- napi.h | 8 +------- test/name.cc | 14 ++++++++++++++ test/name.js | 5 +++++ 4 files changed, 21 insertions(+), 14 deletions(-) diff --git a/napi-inl.h b/napi-inl.h index b7cf63c1b..99c110a80 100644 --- a/napi-inl.h +++ b/napi-inl.h @@ -18,11 +18,9 @@ #if NAPI_HAS_THREADS #include #endif // NAPI_HAS_THREADS +#include #include #include -#if __cplusplus >= 201703L -#include -#endif #if defined(__clang__) || defined(__GNUC__) #define NAPI_NO_SANITIZE_VPTR __attribute__((no_sanitize("vptr"))) @@ -1258,11 +1256,9 @@ inline String String::New(napi_env env, const std::u16string& val) { return String::New(env, val.c_str(), val.size()); } -#if __cplusplus >= 201703L inline String String::New(napi_env env, std::string_view val) { return String::New(env, val.data(), val.size()); } -#endif inline String String::New(napi_env env, const char* val) { // TODO(@gabrielschulhof) Remove if-statement when core's error handling is @@ -1373,12 +1369,10 @@ inline Symbol Symbol::New(napi_env env, const std::string& description) { return Symbol::New(env, descriptionValue); } -#if __cplusplus >= 201703L inline Symbol Symbol::New(napi_env env, std::string_view description) { napi_value descriptionValue = String::New(env, description); return Symbol::New(env, descriptionValue); } -#endif inline Symbol Symbol::New(napi_env env, String description) { napi_value descriptionValue = description; diff --git a/napi.h b/napi.h index d9c4c4add..7a7363082 100644 --- a/napi.h +++ b/napi.h @@ -18,10 +18,8 @@ #include #endif // NAPI_HAS_THREADS #include -#include -#if __cplusplus >= 201703L #include -#endif +#include // VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known // good version) @@ -721,12 +719,10 @@ class String : public Name { const std::u16string& value ///< UTF-16 encoded C++ string ); -#if __cplusplus >= 201703L /// Creates a new String value from a UTF-8 encoded C++ string view. static String New(napi_env env, ///< Node-API environment std::string_view value ///< UTF-8 encoded C++ string view ); -#endif /// Creates a new String value from a UTF-8 encoded C string. static String New( @@ -801,14 +797,12 @@ class Symbol : public Name { description ///< UTF-8 encoded C++ string describing the symbol ); -#if __cplusplus >= 201703L /// Creates a new Symbol value with a description. static Symbol New( napi_env env, ///< Node-API environment std::string_view description ///< UTF-8 encoded C++ string view describing the symbol ); -#endif /// Creates a new Symbol value with a description. static Symbol New(napi_env env, ///< Node-API environment diff --git a/test/name.cc b/test/name.cc index 27bab9312..d94a3937f 100644 --- a/test/name.cc +++ b/test/name.cc @@ -1,5 +1,7 @@ #include "napi.h" +#include + using namespace Napi; const char* testValueUtf8 = "123456789"; @@ -43,6 +45,10 @@ Value CreateString(const CallbackInfo& info) { } } +Value CreateStringFromStringView(const CallbackInfo& info) { + return String::New(info.Env(), std::string_view("hello1")); +} + Value CheckString(const CallbackInfo& info) { String value = info[0].As(); String encoding = info[1].As(); @@ -80,6 +86,10 @@ Value CreateSymbol(const CallbackInfo& info) { } } +Value CreateSymbolFromStringView(const CallbackInfo& info) { + return Symbol::New(info.Env(), std::string_view("hello2")); +} + Value CheckSymbol(const CallbackInfo& info) { return Boolean::New(info.Env(), info[0].Type() == napi_symbol); } @@ -99,11 +109,15 @@ Object InitName(Env env) { exports["echoString"] = Function::New(env, EchoString); exports["createString"] = Function::New(env, CreateString); + exports["createStringFromStringView"] = + Function::New(env, CreateStringFromStringView); exports["nullStringShouldThrow"] = Function::New(env, NullStringShouldThrow); exports["nullString16ShouldThrow"] = Function::New(env, NullString16ShouldThrow); exports["checkString"] = Function::New(env, CheckString); exports["createSymbol"] = Function::New(env, CreateSymbol); + exports["createSymbolFromStringView"] = + Function::New(env, CreateSymbolFromStringView); exports["checkSymbol"] = Function::New(env, CheckSymbol); return exports; diff --git a/test/name.js b/test/name.js index 406c533e3..8113565c8 100644 --- a/test/name.js +++ b/test/name.js @@ -56,4 +56,9 @@ function test (binding) { assert.strictEqual(binding.name.echoString(str, 'utf8'), str); assert.strictEqual(binding.name.echoString(str, 'utf16'), str); } + + assert.strictEqual(binding.name.createStringFromStringView(), 'hello1'); + const symFromStringView = binding.name.createSymbolFromStringView(); + assert.strictEqual(typeof symFromStringView, 'symbol'); + assert.strictEqual(symFromStringView.description, 'hello2'); } From 79d46dc31829bb441bb31f3b879b3c8779190e70 Mon Sep 17 00:00:00 2001 From: Charles Cabergs Date: Tue, 31 Mar 2026 20:24:11 +0200 Subject: [PATCH 4/4] Add doc for String and Symbol string_view constructors --- doc/string.md | 2 ++ doc/symbol.md | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/string.md b/doc/string.md index bb04f664b..7a94a4d3d 100644 --- a/doc/string.md +++ b/doc/string.md @@ -60,6 +60,7 @@ Napi::String::New(napi_env env, const char* value); Napi::String::New(napi_env env, const char16_t* value); Napi::String::New(napi_env env, const char* value, size_t length); Napi::String::New(napi_env env, const char16_t* value, size_t length); +Napi::String::New(napi_env env, std::string_view value); ``` - `[in] env`: The `napi_env` environment in which to construct the `Napi::Value` object. @@ -68,6 +69,7 @@ Napi::String::New(napi_env env, const char16_t* value, size_t length); - `std::u16string&` - represents a UTF16-LE string. - `const char*` - represents a UTF8 string. - `const char16_t*` - represents a UTF16-LE string. + - `std::string_view` - represents a UTF8 string view. - `[in] length`: The length of the string (not necessarily null-terminated) in code units. Returns a new `Napi::String` that represents the passed in C++ string. diff --git a/doc/symbol.md b/doc/symbol.md index e2332674d..d94a618ec 100644 --- a/doc/symbol.md +++ b/doc/symbol.md @@ -18,6 +18,7 @@ Returns a new empty `Napi::Symbol`. ```cpp Napi::Symbol::New(napi_env env, const std::string& description); Napi::Symbol::New(napi_env env, const char* description); +Napi::Symbol::New(napi_env env, std::string_view description); Napi::Symbol::New(napi_env env, Napi::String description); Napi::Symbol::New(napi_env env, napi_value description); ``` @@ -27,6 +28,7 @@ Napi::Symbol::New(napi_env env, napi_value description); `description` may be any of: - `std::string&` - UTF8 string description. - `const char*` - represents a UTF8 string description. + - `std::string_view` - represents a UTF8 string view. - `String` - Node addon API String description. - `napi_value` - Node-API `napi_value` description. @@ -58,4 +60,4 @@ static Napi::Symbol Napi::Symbol::For(napi_env env, napi_value description); Searches in the global registry for existing symbol with the given name. If the symbol already exist it will be returned, otherwise a new symbol will be created in the registry. It's equivalent to Symbol.for() called from JavaScript. -[`Napi::Name`]: ./name.md \ No newline at end of file +[`Napi::Name`]: ./name.md