rename ArrayProxy to ElementProxy and ObjectProxy to PropertyProxy
[jansson.git] / janssonxx.h
index 935ac9e..bac4317 100644 (file)
@@ -22,150 +22,206 @@ namespace jansson {
        class Iterator;
        class Value;
 
-       // base class for JSON value interface
-       template <typename _Base>
-       class _ValueBase : public _Base {
-       public:
-               // empty constructor
-               _ValueBase() : _Base() {}
+       namespace _private {
+               class ElementProxy;
+               class PropertyProxy;
+
+               // base class for JSON value interface
+               template <typename _Base>
+               class ValueBase : public _Base {
+               public:
+                       // empty constructor
+                       ValueBase() : _Base() {}
+
+                       // copy constructor
+                       ValueBase(const _Base& base) : _Base(base) {}
+
+                       // create reference to value
+                       ValueBase(json_t* json) : _Base(json) {}
+
+                       // assignment operator
+                       ValueBase& operator=(const Value& value) { _Base::operator=(value); return *this; }
+
+                       // check value type
+                       bool is_undefined() const { return _Base::as_json() == 0; }
+                       bool is_object() const { return json_is_object(_Base::as_json()); }
+                       bool is_array() const { return json_is_array(_Base::as_json()); }
+                       bool is_string() const { return json_is_string(_Base::as_json()); }
+                       bool is_integer() const { return json_is_integer(_Base::as_json()); }
+                       bool is_real() const { return json_is_real(_Base::as_json()); }
+                       bool is_number() const { return json_is_number(_Base::as_json()); }
+                       bool is_true() const { return json_is_true(_Base::as_json()); }
+                       bool is_false() const { return json_is_false(_Base::as_json()); }
+                       bool is_boolean() const { return json_is_boolean(_Base::as_json()); }
+                       bool is_null() const { return json_is_null(_Base::as_json()); }
+
+                       // get size of array or object
+                       inline unsigned int size() const;
+
+                       // get value at array index (const version)
+                       inline const Value at(unsigned int index) const;
+
+                       inline const Value operator[](signed int index) const;
+                       inline const Value operator[](unsigned int index) const;
+                       inline const Value operator[](signed short index) const;
+                       inline const Value operator[](unsigned short index) const;
+                       inline const Value operator[](signed long index) const;
+                       inline const Value operator[](unsigned long index) const;
+
+                       // get value at array index (non-const version)
+                       inline ValueBase<ElementProxy> at(unsigned int index);
+
+                       inline ValueBase<ElementProxy> operator[](signed int index);
+                       inline ValueBase<ElementProxy> operator[](unsigned int index);
+                       inline ValueBase<ElementProxy> operator[](signed short index);
+                       inline ValueBase<ElementProxy> operator[](unsigned short index);
+                       inline ValueBase<ElementProxy> operator[](signed long index);
+                       inline ValueBase<ElementProxy> operator[](unsigned long index);
+
+                       // get object property (const version)
+                       inline const Value get(const char* key) const;
+
+                       inline const Value get(const std::string& key) const;
+                       inline const Value operator[](const char* key) const;
+                       inline const Value operator[](const std::string& key) const;
+
+                       // get object property (non-const version)
+                       inline ValueBase<PropertyProxy> get(const char* key);
+
+                       inline ValueBase<PropertyProxy> get(const std::string& key);
+                       inline ValueBase<PropertyProxy> operator[](const char* key);
+                       inline ValueBase<PropertyProxy> operator[](const std::string& key);
+
+                       // clear all array/object values
+                       inline void clear();
+
+                       // get value cast to specified type
+                       inline const char* as_cstring() const;
+                       inline std::string as_string() const;
+                       inline int as_integer() const;
+                       inline double as_real() const;
+                       inline double as_number() const;
+                       inline bool as_boolean() const;
+
+                       // set an object property (converts value to object is not one already)
+                       inline _Base& set_key(const char* key, const Value& value);
+
+                       inline _Base& set_key(const std::string& key, const Value& value);
+
+                       // set an array index (converts value to object is not one already)
+                       inline _Base& set_at(unsigned int index, const Value& value);
+
+                       // delete an object key
+                       inline _Base& del_key(const char* key);
+
+                       inline _Base& del_key(const std::string& key);
+
+                       // delete an item from an array by index
+                       inline _Base& del_at(unsigned int index);
+
+                       // insert an item into an array at a given index
+                       inline _Base& insert_at(unsigned int index, const Value& value);
+               };
+
+               // represents any JSON value, private base
+               class Basic {
+               public:
+                       // construct new Value with an undefined value
+                       Basic() : _value(0) {}
+
+                       // copy constructor
+                       Basic(const Basic& value) : _value(json_incref(value._value)) {}
+
+                       // make a reference to an existing json_t value
+                       explicit Basic(json_t* value) : _value(json_incref(value)) {}
+
+                       // free Value resources
+                       ~Basic() { json_decref(_value); }
+
+                       // copy an existing Value
+                       Basic& operator=(const Basic& e) {
+                               if (&e != this) {
+                                       json_decref(_value);
+                                       _value = json_incref(e._value);
+                               }
+                               return *this;
+                       }
 
-               // copy constructor
-               _ValueBase(const _Base& base) : _Base(base) {}
+                       // get the underlying json_t
+                       json_t* as_json() const { return _value; }
 
-               // create reference to value
-               _ValueBase(json_t* json) : _Base(json) {}
-
-               // check value type
-               bool is_undefined() const { return _Base::as_json() == 0; }
-               bool is_object() const { return json_is_object(_Base::as_json()); }
-               bool is_array() const { return json_is_array(_Base::as_json()); }
-               bool is_string() const { return json_is_string(_Base::as_json()); }
-               bool is_integer() const { return json_is_integer(_Base::as_json()); }
-               bool is_real() const { return json_is_real(_Base::as_json()); }
-               bool is_number() const { return json_is_number(_Base::as_json()); }
-               bool is_true() const { return json_is_true(_Base::as_json()); }
-               bool is_false() const { return json_is_false(_Base::as_json()); }
-               bool is_boolean() const { return json_is_boolean(_Base::as_json()); }
-               bool is_null() const { return json_is_null(_Base::as_json()); }
-
-               // get size of array or object
-               inline unsigned int size() const;
-
-               // get value at array index (const version)
-               inline const Value at(unsigned int index) const;
-
-               inline const Value operator[](signed int index) const;
-               inline const Value operator[](unsigned int index) const;
-               inline const Value operator[](signed short index) const;
-               inline const Value operator[](unsigned short index) const;
-               inline const Value operator[](signed long index) const;
-               inline const Value operator[](unsigned long index) const;
-
-               // get value at array index (non-const version)
-               inline Value at(unsigned int index);
-
-               inline Value operator[](signed int index);
-               inline Value operator[](unsigned int index);
-               inline Value operator[](signed short index);
-               inline Value operator[](unsigned short index);
-               inline Value operator[](signed long index);
-               inline Value operator[](unsigned long index);
-
-               // get object property
-               inline const Value get(const char* key) const;
-
-               inline const Value get(const std::string& key) const;
-               inline const Value operator[](const char* key) const;
-               inline const Value operator[](const std::string& key) const;
-
-               // clear all array/object values
-               inline void clear();
-
-               // get value cast to specified type
-               inline const char* as_cstring() const;
-               inline std::string as_string() const;
-               inline int as_integer() const;
-               inline double as_real() const;
-               inline double as_number() const;
-               inline bool as_boolean() const;
-
-               // set an object property (converts value to object is not one already)
-               inline _Base& set_key(const char* key, const Value& value);
-
-               inline _Base& set_key(const std::string& key, const Value& value);
-
-               // set an array index (converts value to object is not one already)
-               inline _Base& set_at(unsigned int index, const Value& value);
-
-               // delete an object key
-               inline _Base& del_key(const char* key);
-
-               inline _Base& del_key(const std::string& key);
-
-               // delete an item from an array by index
-               inline _Base& del_at(unsigned int index);
-
-               // insert an item into an array at a given index
-               inline _Base& insert_at(unsigned int index, const Value& value);
-       };
+               protected:
+                       // take ownership of a json_t (does not increase reference count)
+                       static Basic _take(json_t* json) {
+                               Basic v;
+                               v._value = json;
+                               return v;
+                       }
 
-       // represents any JSON value, private base
-       class _Value {
-       public:
-               // construct new Value with an undefined value
-               _Value() : _value(0) {}
+               private:
+                       // internal value pointer
+                       json_t* _value;
+               };
 
-               // copy constructor
-               _Value(const _Value& value) : _value(json_incref(value._value)) {}
+               // proxies an array element
+               class ElementProxy {
+               public:
+                       // constructor
+                       ElementProxy(json_t* array, unsigned int index) : _array(array), _index(index) {}
 
-               // make a reference to an existing json_t value
-               explicit _Value(json_t* value) : _value(json_incref(value)) {}
+                       // assign to the proxied element
+                       inline ElementProxy& operator=(const Value& value);
 
-               // free Value resources
-               ~_Value() { json_decref(_value); }
+                       // get the proxied element
+                       json_t* as_json() const { return json_array_get(_array, _index); }
 
-               // copy an existing Value
-               _Value& operator=(const _Value& e) {
-                       if (&e != this) {
-                               json_decref(_value);
-                               _value = json_incref(e._value);
-                       }
-                       return *this;
-               }
+               private:
+                       // array object we wrap
+                       json_t* _array;
 
-               // get the underlying json_t
-               json_t* as_json() const { return _value; }
+                       // index of property
+                       unsigned int _index;
+               };
 
-       protected:
-               // take ownership of a json_t (does not increase reference count)
-               static _Value _take(json_t* json) {
-                       _Value v;
-                       v._value = json;
-                       return v;
-               }
+               // proxies an object property
+               class PropertyProxy {
+               public:
+                       // constructor
+                       PropertyProxy(json_t* array, const char* key) : _object(array), _key(key) {}
 
-       private:
-               // internal value pointer
-               json_t* _value;
-       };
+                       // assign to the proxied element
+                       inline PropertyProxy& operator=(const Value& value);
+
+                       // get the proxied element
+                       json_t* as_json() const { return json_object_get(_object, _key); }
+
+               private:
+                       // array object we wrap
+                       json_t* _object;
+
+                       // key of property
+                       const char* _key;
+               };
+
+       } // namespace jansson::_private
 
        // represents any JSON value
-       class Value : public _ValueBase<_Value> {
+       class Value : public _private::ValueBase<_private::Basic> {
        public:
                // empty constructor
-               Value() : _ValueBase<_Value>() {}
+               Value() : _private::ValueBase<_private::Basic>() {}
 
                // copy constructor for base
-               Value(const _Value& value) : _ValueBase<_Value>(value) {}
+               Value(const _private::Basic& value) : _private::ValueBase<_private::Basic>(value) {}
        
                // copy constructor for base
-               Value(const _ValueBase<_Value>& value) : _ValueBase<_Value>(value) {}
+               Value(const _private::ValueBase<_private::Basic>& value) : _private::ValueBase<_private::Basic>(value) {}
 
                // copy constructor
-               Value(const Value& value) : _ValueBase<_Value>(value) {}
+               Value(const Value& value) : _private::ValueBase<_private::Basic>(value) {}
 
                // create reference to value
-               explicit Value(json_t* json) : _ValueBase<_Value>(json) {}
+               explicit Value(json_t* json) : _private::ValueBase<_private::Basic>(json) {}
 
                // construct Value from input
                static inline Value from(const char* value) { return Value::_take(json_string(value)); }
@@ -218,6 +274,11 @@ namespace jansson {
                        _iter = json_object_iter(_object.as_json());
                }
 
+               // construct a new iterator for a given object
+               Iterator(const _private::ValueBase<_private::PropertyProxy>& value) : _object(value.as_json()), _iter(0) {
+                       _iter = json_object_iter(_object.as_json());
+               }
+
                // increment iterator
                void next() {
                        _iter = json_object_iter_next(_object.as_json(), _iter);