Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#550 Fix iterator related compiling issues for Intel icc #598

Merged
merged 8 commits into from
Jun 6, 2017
53 changes: 19 additions & 34 deletions src/json.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8053,50 +8053,35 @@ class basic_json
}
}

/*
Use operator `const_iterator` instead of `const_iterator(const iterator&
other) noexcept` to avoid two class definitions for @ref iterator and
@ref const_iterator.

This function is only called if this class is an @ref iterator. If this
class is a @ref const_iterator this function is not called.
/*!
@note The conventional copy constructor and copy assignment are
implicitly defined.
Combined with the following converting constructor and assigment,
they support: copy from iterator to iterator,
copy from const iterator to const iterator,
and conversion from iterator to const iterator.
However conversion from const iterator to iterator is not defined.
*/
operator const_iterator() const
{
const_iterator ret;

if (m_object)
{
ret.m_object = m_object;
ret.m_it = m_it;
}

return ret;
}

/*!
@brief copy constructor
@param[in] other iterator to copy from
@brief converting constructor
@param[in] other non-const iterator to copy from
@note It is not checked whether @a other is initialized.
*/
iter_impl(const iter_impl& other) noexcept
iter_impl(const iter_impl<basic_json>& other) noexcept
: m_object(other.m_object), m_it(other.m_it)
{}

/*!
@brief copy assignment
@param[in,out] other iterator to copy from
@brief converting assignment
@param[in,out] other non-const iterator to copy from
@return const/non-const iterator
@note It is not checked whether @a other is initialized.
*/
iter_impl& operator=(iter_impl other) noexcept(
std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and
std::is_nothrow_move_assignable<internal_iterator>::value
)
{
std::swap(m_object, other.m_object);
std::swap(m_it, other.m_it);
iter_impl& operator=(const iter_impl<basic_json>& other) noexcept
{
m_object = other.m_object;
m_it = other.m_it;
return *this;
}

Expand Down Expand Up @@ -8585,7 +8570,7 @@ class basic_json
/// associated JSON instance
pointer m_object = nullptr;
/// the actual iterator of the associated instance
internal_iterator m_it = internal_iterator();
struct internal_iterator m_it = internal_iterator();
};

/*!
Expand Down
68 changes: 68 additions & 0 deletions test/src/unit-iterators1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1511,4 +1511,72 @@ TEST_CASE("iterators 1")
}
}
}

SECTION("conversion from iterator to const iterator")
{
SECTION("boolean")
{
json j = true;
json::const_iterator it = j.begin();
CHECK(it == j.cbegin());
it = j.begin();
CHECK(it == j.cbegin());
}
SECTION("string")
{
json j = "hello world";
json::const_iterator it = j.begin();
CHECK(it == j.cbegin());
it = j.begin();
CHECK(it == j.cbegin());
}
SECTION("array")
{
json j = {1, 2, 3};
json::const_iterator it = j.begin();
CHECK(it == j.cbegin());
it = j.begin();
CHECK(it == j.cbegin());
}
SECTION("object")
{
json j = {{"A", 1}, {"B", 2}, {"C", 3}};
json::const_iterator it = j.begin();
CHECK(it == j.cbegin());
it = j.begin();
CHECK(it == j.cbegin());
}
SECTION("number (integer)")
{
json j = 23;
json::const_iterator it = j.begin();
CHECK(it == j.cbegin());
it = j.begin();
CHECK(it == j.cbegin());
}
SECTION("number (unsigned)")
{
json j = 23u;
json::const_iterator it = j.begin();
CHECK(it == j.cbegin());
it = j.begin();
CHECK(it == j.cbegin());
}
SECTION("number (float)")
{
json j = 23.42;
json::const_iterator it = j.begin();
CHECK(it == j.cbegin());
it = j.begin();
CHECK(it == j.cbegin());
}
SECTION("null")
{
json j = nullptr;
json::const_iterator it = j.begin();
CHECK(it == j.cbegin());
it = j.begin();
CHECK(it == j.cbegin());
}
}
}