From b082693b9ebbb6e0402c7c95f4d8b9cd262595c8 Mon Sep 17 00:00:00 2001 From: Hans Johnson Date: Thu, 17 Oct 2019 12:52:13 -0500 Subject: [PATCH] COMP: Improve const correctness for ValueIterators (#1056) The protected deref method had inconsistent interface of being a const function that returned a non-const reference. Resolves #914. --- include/json/value.h | 19 +++++++++++++++---- src/lib_json/json_valueiterator.inl | 3 ++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/json/value.h b/include/json/value.h index 5c10163..d0af711 100644 --- a/include/json/value.h +++ b/include/json/value.h @@ -772,7 +772,14 @@ public: char const* memberName(char const** end) const; protected: - Value& deref() const; + /*! Internal utility functions to assist with implementing + * other iterator functions. The const and non-const versions + * of the "deref" protected methods expose the protected + * current_ member variable in a way that can often be + * optimized away by the compiler. + */ + const Value& deref() const; + Value& deref(); void increment(); @@ -895,9 +902,13 @@ public: return *this; } - reference operator*() const { return deref(); } - - pointer operator->() const { return &deref(); } + /*! The return value of non-const iterators can be + * changed, so the these functions are not const + * because the returned references/pointers can be used + * to change state of the base class. + */ + reference operator*() { return deref(); } + pointer operator->() { return &deref(); } }; inline void swap(Value& a, Value& b) { a.swap(b); } diff --git a/src/lib_json/json_valueiterator.inl b/src/lib_json/json_valueiterator.inl index 4a3d210..9bd9315 100644 --- a/src/lib_json/json_valueiterator.inl +++ b/src/lib_json/json_valueiterator.inl @@ -21,7 +21,8 @@ ValueIteratorBase::ValueIteratorBase( const Value::ObjectValues::iterator& current) : current_(current), isNull_(false) {} -Value& ValueIteratorBase::deref() const { return current_->second; } +Value& ValueIteratorBase::deref() { return current_->second; } +const Value& ValueIteratorBase::deref() const { return current_->second; } void ValueIteratorBase::increment() { ++current_; }