diff --git a/include/nlohmann/detail/iterators/iter_impl.hpp b/include/nlohmann/detail/iterators/iter_impl.hpp
index 434a62d3e5..d8060786ec 100644
--- a/include/nlohmann/detail/iterators/iter_impl.hpp
+++ b/include/nlohmann/detail/iterators/iter_impl.hpp
@@ -352,7 +352,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@brief post-increment (it++)
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
- iter_impl const operator++(int) // NOLINT(readability-const-return-type)
+ iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
++(*this);
@@ -403,7 +403,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@brief post-decrement (it--)
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
- iter_impl const operator--(int) // NOLINT(readability-const-return-type)
+ iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
--(*this);
diff --git a/include/nlohmann/detail/iterators/json_reverse_iterator.hpp b/include/nlohmann/detail/iterators/json_reverse_iterator.hpp
index e787fdbcd7..65bb327a57 100644
--- a/include/nlohmann/detail/iterators/json_reverse_iterator.hpp
+++ b/include/nlohmann/detail/iterators/json_reverse_iterator.hpp
@@ -48,7 +48,7 @@ class json_reverse_iterator : public std::reverse_iterator
explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
/// post-increment (it++)
- json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
+ json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
{
return static_cast(base_iterator::operator++(1));
}
@@ -60,7 +60,7 @@ class json_reverse_iterator : public std::reverse_iterator
}
/// post-decrement (it--)
- json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
+ json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
{
return static_cast(base_iterator::operator--(1));
}
diff --git a/include/nlohmann/detail/iterators/primitive_iterator.hpp b/include/nlohmann/detail/iterators/primitive_iterator.hpp
index 15aa2f08aa..03bc37e2c7 100644
--- a/include/nlohmann/detail/iterators/primitive_iterator.hpp
+++ b/include/nlohmann/detail/iterators/primitive_iterator.hpp
@@ -87,7 +87,7 @@ class primitive_iterator_t
return *this;
}
- primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
+ primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
++m_it;
@@ -100,7 +100,7 @@ class primitive_iterator_t
return *this;
}
- primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
+ primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
--m_it;
diff --git a/single_include/nlohmann/json.hpp b/single_include/nlohmann/json.hpp
index 48999920dd..05000fbba4 100644
--- a/single_include/nlohmann/json.hpp
+++ b/single_include/nlohmann/json.hpp
@@ -11308,7 +11308,7 @@ class primitive_iterator_t
return *this;
}
- primitive_iterator_t const operator++(int) noexcept // NOLINT(readability-const-return-type)
+ primitive_iterator_t operator++(int)& noexcept // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
++m_it;
@@ -11321,7 +11321,7 @@ class primitive_iterator_t
return *this;
}
- primitive_iterator_t const operator--(int) noexcept // NOLINT(readability-const-return-type)
+ primitive_iterator_t operator--(int)& noexcept // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
--m_it;
@@ -11728,7 +11728,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@brief post-increment (it++)
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
- iter_impl const operator++(int) // NOLINT(readability-const-return-type)
+ iter_impl operator++(int)& // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
++(*this);
@@ -11779,7 +11779,7 @@ class iter_impl // NOLINT(cppcoreguidelines-special-member-functions,hicpp-speci
@brief post-decrement (it--)
@pre The iterator is initialized; i.e. `m_object != nullptr`.
*/
- iter_impl const operator--(int) // NOLINT(readability-const-return-type)
+ iter_impl operator--(int)& // NOLINT(cert-dcl21-cpp)
{
auto result = *this;
--(*this);
@@ -12167,7 +12167,7 @@ class json_reverse_iterator : public std::reverse_iterator
explicit json_reverse_iterator(const base_iterator& it) noexcept : base_iterator(it) {}
/// post-increment (it++)
- json_reverse_iterator const operator++(int) // NOLINT(readability-const-return-type)
+ json_reverse_iterator operator++(int)& // NOLINT(cert-dcl21-cpp)
{
return static_cast(base_iterator::operator++(1));
}
@@ -12179,7 +12179,7 @@ class json_reverse_iterator : public std::reverse_iterator
}
/// post-decrement (it--)
- json_reverse_iterator const operator--(int) // NOLINT(readability-const-return-type)
+ json_reverse_iterator operator--(int)& // NOLINT(cert-dcl21-cpp)
{
return static_cast(base_iterator::operator--(1));
}
diff --git a/test/src/unit-class_iterator.cpp b/test/src/unit-class_iterator.cpp
index 0e159fc381..e3a972f97c 100644
--- a/test/src/unit-class_iterator.cpp
+++ b/test/src/unit-class_iterator.cpp
@@ -33,6 +33,12 @@ SOFTWARE.
#include
using nlohmann::json;
+template
+using can_post_increment_temporary = decltype((std::declval()++)++);
+
+template
+using can_post_decrement_temporary = decltype((std::declval()--)--);
+
TEST_CASE("iterator class")
{
SECTION("construction")
@@ -399,4 +405,89 @@ TEST_CASE("iterator class")
}
}
}
+ SECTION("equality-preserving")
+ {
+ SECTION("post-increment")
+ {
+ SECTION("primitive_iterator_t")
+ {
+ using Iter = nlohmann::detail::primitive_iterator_t;
+ CHECK(std::is_same < decltype(std::declval()++), Iter >::value);
+ }
+ SECTION("iter_impl")
+ {
+ using Iter = nlohmann::detail::iter_impl;
+ CHECK(std::is_same < decltype(std::declval()++), Iter >::value);
+ }
+ SECTION("json_reverse_iterator")
+ {
+ using Base = nlohmann::detail::iter_impl;
+ using Iter = nlohmann::detail::json_reverse_iterator;
+ CHECK(std::is_same < decltype(std::declval()++), Iter >::value);
+ }
+ }
+ SECTION("post-decrement")
+ {
+ SECTION("primitive_iterator_t")
+ {
+ using Iter = nlohmann::detail::primitive_iterator_t;
+ CHECK(std::is_same < decltype(std::declval()--), Iter >::value);
+ }
+ SECTION("iter_impl")
+ {
+ using Iter = nlohmann::detail::iter_impl;
+ CHECK(std::is_same < decltype(std::declval()--), Iter >::value );
+ }
+ SECTION("json_reverse_iterator")
+ {
+ using Base = nlohmann::detail::iter_impl;
+ using Iter = nlohmann::detail::json_reverse_iterator;
+ CHECK(std::is_same < decltype(std::declval()--), Iter >::value );
+ }
+ }
+ }
+ // prevent "accidental mutation of a temporary object"
+ SECTION("cert-dcl21-cpp")
+ {
+ using nlohmann::detail::is_detected;
+ SECTION("post-increment")
+ {
+ SECTION("primitive_iterator_t")
+ {
+ using Iter = nlohmann::detail::primitive_iterator_t;
+ CHECK_FALSE(is_detected::value);
+ }
+ SECTION("iter_impl")
+ {
+ using Iter = nlohmann::detail::iter_impl;
+ CHECK_FALSE(is_detected::value);
+ }
+ SECTION("json_reverse_iterator")
+ {
+ using Base = nlohmann::detail::iter_impl;
+ using Iter = nlohmann::detail::json_reverse_iterator;
+ CHECK_FALSE(is_detected::value);
+ }
+ }
+ SECTION("post-decrement")
+ {
+ SECTION("primitive_iterator_t")
+ {
+ using Iter = nlohmann::detail::primitive_iterator_t;
+ CHECK_FALSE(is_detected::value);
+ }
+ SECTION("iter_impl")
+ {
+ using Iter = nlohmann::detail::iter_impl;
+ CHECK_FALSE(is_detected::value);
+ }
+ SECTION("json_reverse_iterator")
+ {
+ using Base = nlohmann::detail::iter_impl;
+ using Iter = nlohmann::detail::json_reverse_iterator;
+ CHECK_FALSE(is_detected::value);
+ }
+
+ }
+ }
}