Merge pull request #598 from HenryRLee/issue550

#550 Fix iterator related compiling issues for Intel icc
This commit is contained in:
Niels Lohmann 2017-06-06 20:41:42 +02:00 committed by GitHub
commit bfdf0d1ce6
2 changed files with 86 additions and 33 deletions

View file

@ -8053,50 +8053,35 @@ class basic_json
} }
} }
/* /*!
Use operator `const_iterator` instead of `const_iterator(const iterator& @note The conventional copy constructor and copy assignment are
other) noexcept` to avoid two class definitions for @ref iterator and implicitly defined.
@ref const_iterator. Combined with the following converting constructor and assigment,
they support: copy from iterator to iterator,
This function is only called if this class is an @ref iterator. If this copy from const iterator to const iterator,
class is a @ref const_iterator this function is not called. 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 @brief converting constructor
@param[in] other iterator to copy from @param[in] other non-const iterator to copy from
@note It is not checked whether @a other is initialized. @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) : m_object(other.m_object), m_it(other.m_it)
{} {}
/*! /*!
@brief copy assignment @brief converting assignment
@param[in,out] other iterator to copy from @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. @note It is not checked whether @a other is initialized.
*/ */
iter_impl& operator=(iter_impl other) noexcept( iter_impl& operator=(const iter_impl<basic_json>& 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); m_object = other.m_object;
std::swap(m_it, other.m_it); m_it = other.m_it;
return *this; return *this;
} }
@ -8585,7 +8570,7 @@ class basic_json
/// associated JSON instance /// associated JSON instance
pointer m_object = nullptr; pointer m_object = nullptr;
/// the actual iterator of the associated instance /// the actual iterator of the associated instance
internal_iterator m_it = internal_iterator(); struct internal_iterator m_it = internal_iterator();
}; };
/*! /*!

View file

@ -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());
}
}
} }