Skip to content

Commit 04b3abd

Browse files
committed
Add l-value return type for Object::operator []
Add a special return type for non-const accesses to `obj[key]` so that `obj[key] = value` notation works.
1 parent ecf47f2 commit 04b3abd

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

napi-inl.h

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,6 +425,21 @@ inline std::u16string String::Utf16Value() const {
425425
// Object class
426426
////////////////////////////////////////////////////////////////////////////////
427427

428+
template <typename Key>
429+
inline PropertyLValue<Key>::operator Value() const {
430+
return _object.Get(_key);
431+
}
432+
433+
template <typename Key> template <typename ValueType>
434+
inline PropertyLValue<Key>& PropertyLValue<Key>::operator =(ValueType value) {
435+
_object.Set(_key, value);
436+
return *this;
437+
}
438+
439+
template <typename Key>
440+
inline PropertyLValue<Key>::PropertyLValue(Object object, Key key)
441+
: _object(object), _key(key) {}
442+
428443
inline Object Object::New(napi_env env) {
429444
napi_value value;
430445
napi_status status = napi_create_object(env, &value);
@@ -438,6 +453,18 @@ inline Object::Object() : Value() {
438453
inline Object::Object(napi_env env, napi_value value) : Value(env, value) {
439454
}
440455

456+
inline PropertyLValue<std::string> Object::operator [](const char* name) {
457+
return PropertyLValue<std::string>(*this, name);
458+
}
459+
460+
inline PropertyLValue<std::string> Object::operator [](const std::string& name) {
461+
return PropertyLValue<std::string>(*this, name);
462+
}
463+
464+
inline PropertyLValue<uint32_t> Object::operator [](uint32_t index) {
465+
return PropertyLValue<uint32_t>(*this, index);
466+
}
467+
441468
inline Value Object::operator [](const char* name) const {
442469
return Get(name);
443470
}

napi.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ namespace Napi {
3636
class PropertyDescriptor;
3737
class CallbackInfo;
3838
template <typename T> class Reference;
39+
template <typename Key> class PropertyLValue;
3940

4041
class TypedArray;
4142
template <typename T, napi_typedarray_type A> class TypedArray_;
@@ -175,6 +176,10 @@ namespace Napi {
175176
Object();
176177
Object(napi_env env, napi_value value);
177178

179+
PropertyLValue<std::string> operator [](const char* name);
180+
PropertyLValue<std::string> operator [](const std::string& name);
181+
PropertyLValue<uint32_t> operator [](uint32_t index);
182+
178183
Value operator [](const char* name) const;
179184
Value operator [](const std::string& name) const;
180185
Value operator [](uint32_t index) const;
@@ -214,6 +219,23 @@ namespace Napi {
214219
bool InstanceOf(const Function& constructor) const;
215220
};
216221

222+
template <typename Key>
223+
class PropertyLValue {
224+
public:
225+
operator Value() const;
226+
227+
// |ValueType| can be anything supported by Object::Set.
228+
template <typename ValueType>
229+
PropertyLValue& operator =(ValueType value);
230+
PropertyLValue() = delete;
231+
private:
232+
PropertyLValue(Object object, Key key);
233+
Object _object;
234+
Key _key;
235+
236+
friend class Napi::Object;
237+
};
238+
217239
template <typename T>
218240
class External : public Value {
219241
public:

0 commit comments

Comments
 (0)