overworked iterators
This commit is contained in:
parent
76be1ae1f6
commit
bbc45eb4d8
4 changed files with 374 additions and 530 deletions
|
@ -42,11 +42,12 @@ due to alignment.
|
|||
*/
|
||||
class json
|
||||
{
|
||||
public:
|
||||
private:
|
||||
// forward declaration to friend this class
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
|
||||
public:
|
||||
// container types
|
||||
using value_type = json;
|
||||
using reference = json&;
|
||||
|
@ -371,15 +372,15 @@ class json
|
|||
/// the payload
|
||||
value value_ {};
|
||||
|
||||
public:
|
||||
private:
|
||||
/// an iterator
|
||||
class iterator : public std::iterator<std::forward_iterator_tag, json>
|
||||
class iterator : private std::iterator<std::forward_iterator_tag, json>
|
||||
{
|
||||
friend class json;
|
||||
friend class json::const_iterator;
|
||||
public:
|
||||
iterator() = default;
|
||||
iterator(json*);
|
||||
iterator(json*, bool);
|
||||
iterator(const iterator&);
|
||||
~iterator();
|
||||
|
||||
|
@ -402,16 +403,18 @@ class json
|
|||
array_t::iterator* vi_ = nullptr;
|
||||
/// an iterator for JSON objects
|
||||
object_t::iterator* oi_ = nullptr;
|
||||
/// whether iterator points to a valid object
|
||||
bool invalid = true;
|
||||
};
|
||||
|
||||
/// a const iterator
|
||||
class const_iterator : public std::iterator<std::forward_iterator_tag, const json>
|
||||
class const_iterator : private std::iterator<std::forward_iterator_tag, const json>
|
||||
{
|
||||
friend class json;
|
||||
|
||||
public:
|
||||
const_iterator() = default;
|
||||
const_iterator(const json*);
|
||||
const_iterator(const json*, bool);
|
||||
const_iterator(const const_iterator&);
|
||||
const_iterator(const json::iterator&);
|
||||
~const_iterator();
|
||||
|
@ -435,6 +438,8 @@ class json
|
|||
array_t::const_iterator* vi_ = nullptr;
|
||||
/// an iterator for JSON objects
|
||||
object_t::const_iterator* oi_ = nullptr;
|
||||
/// whether iterator reached past the end
|
||||
bool invalid = true;
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -1769,50 +1774,28 @@ json::const_iterator json::find(const std::string& key) const
|
|||
|
||||
json::iterator json::find(const char* key)
|
||||
{
|
||||
if (type_ != value_t::object)
|
||||
auto result = end();
|
||||
|
||||
if (type_ == value_t::object)
|
||||
{
|
||||
return end();
|
||||
}
|
||||
else
|
||||
{
|
||||
const object_t::iterator i = value_.object->find(key);
|
||||
if (i != value_.object->end())
|
||||
{
|
||||
json::iterator result(this);
|
||||
delete result.oi_;
|
||||
result.oi_ = nullptr;
|
||||
result.oi_ = new object_t::iterator(i);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return end();
|
||||
}
|
||||
result.oi_ = new object_t::iterator(value_.object->find(key));
|
||||
result.invalid = (*(result.oi_) == value_.object->end());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
json::const_iterator json::find(const char* key) const
|
||||
{
|
||||
if (type_ != value_t::object)
|
||||
auto result = cend();
|
||||
|
||||
if (type_ == value_t::object)
|
||||
{
|
||||
return end();
|
||||
}
|
||||
else
|
||||
{
|
||||
const object_t::const_iterator i = value_.object->find(key);
|
||||
if (i != value_.object->end())
|
||||
{
|
||||
json::const_iterator result(this);
|
||||
delete result.oi_;
|
||||
result.oi_ = nullptr;
|
||||
result.oi_ = new object_t::const_iterator(i);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return end();
|
||||
}
|
||||
result.oi_ = new object_t::const_iterator(value_.object->find(key));
|
||||
result.invalid = (*(result.oi_) == value_.object->cend());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool json::operator==(const json& o) const noexcept
|
||||
|
@ -1896,90 +1879,78 @@ bool json::operator!=(const json& o) const noexcept
|
|||
|
||||
json::iterator json::begin() noexcept
|
||||
{
|
||||
return json::iterator(this);
|
||||
return json::iterator(this, true);
|
||||
}
|
||||
|
||||
json::iterator json::end() noexcept
|
||||
{
|
||||
return json::iterator();
|
||||
return json::iterator(this, false);
|
||||
}
|
||||
|
||||
json::const_iterator json::begin() const noexcept
|
||||
{
|
||||
return json::const_iterator(this);
|
||||
return json::const_iterator(this, true);
|
||||
}
|
||||
|
||||
json::const_iterator json::end() const noexcept
|
||||
{
|
||||
return json::const_iterator();
|
||||
return json::const_iterator(this, false);
|
||||
}
|
||||
|
||||
json::const_iterator json::cbegin() const noexcept
|
||||
{
|
||||
return json::const_iterator(this);
|
||||
return json::const_iterator(this, true);
|
||||
}
|
||||
|
||||
json::const_iterator json::cend() const noexcept
|
||||
{
|
||||
return json::const_iterator();
|
||||
return json::const_iterator(this, false);
|
||||
}
|
||||
|
||||
|
||||
json::iterator::iterator(json* j) : object_(j)
|
||||
json::iterator::iterator(json* j, bool begin)
|
||||
: object_(j), invalid(not begin or j == nullptr)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
if (begin)
|
||||
{
|
||||
object_ = nullptr;
|
||||
vi_ = new array_t::iterator(object_->value_.array->begin());
|
||||
invalid = (*vi_ == object_->value_.array->end());
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::iterator(object_->value_.array->begin());
|
||||
vi_ = new array_t::iterator(object_->value_.array->end());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
if (begin)
|
||||
{
|
||||
object_ = nullptr;
|
||||
oi_ = new object_t::iterator(object_->value_.object->begin());
|
||||
invalid = (*oi_ == object_->value_.object->end());
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::iterator(object_->value_.object->begin());
|
||||
oi_ = new object_t::iterator(object_->value_.object->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json::iterator::iterator(const json::iterator& o) : object_(o.object_)
|
||||
json::iterator::iterator(const json::iterator& o)
|
||||
: object_(o.object_), invalid(o.invalid)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
if (o.vi_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::iterator(object_->value_.array->begin());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::iterator(object_->value_.object->begin());
|
||||
}
|
||||
}
|
||||
vi_ = new array_t::iterator(*(o.vi_));
|
||||
}
|
||||
|
||||
if (o.oi_ != nullptr)
|
||||
{
|
||||
oi_ = new object_t::iterator(*(o.oi_));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1994,29 +1965,29 @@ json::iterator& json::iterator::operator=(json::iterator o)
|
|||
std::swap(object_, o.object_);
|
||||
std::swap(vi_, o.vi_);
|
||||
std::swap(oi_, o.oi_);
|
||||
std::swap(invalid, o.invalid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool json::iterator::operator==(const json::iterator& o) const
|
||||
{
|
||||
if (object_ != o.object_)
|
||||
if (object_ != nullptr and o.object_ != nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
if (object_->type_ == json::value_t::array and o.object_->type_ == json::value_t::array)
|
||||
{
|
||||
return (vi_ == o.vi_);
|
||||
return (*vi_ == *(o.vi_));
|
||||
}
|
||||
if (object_->type_ == json::value_t::object)
|
||||
if (object_->type_ == json::value_t::object and o.object_->type_ == json::value_t::object)
|
||||
{
|
||||
return (oi_ == o.oi_);
|
||||
return (*oi_ == *(o.oi_));
|
||||
}
|
||||
|
||||
if (invalid == o.invalid and object_ == o.object_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool json::iterator::operator!=(const json::iterator& o) const
|
||||
|
@ -2026,44 +1997,38 @@ bool json::iterator::operator!=(const json::iterator& o) const
|
|||
|
||||
json::iterator& json::iterator::operator++()
|
||||
{
|
||||
// iterator cannot be incremented
|
||||
if (object_ == nullptr)
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
return *this;
|
||||
switch (object_->type_)
|
||||
{
|
||||
case (json::value_t::array):
|
||||
{
|
||||
std::advance(*vi_, 1);
|
||||
invalid = (*vi_ == object_->value_.array->end());
|
||||
break;
|
||||
}
|
||||
case (json::value_t::object):
|
||||
{
|
||||
std::advance(*oi_, 1);
|
||||
invalid = (*oi_ == object_->value_.object->end());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
{
|
||||
case (json::value_t::array):
|
||||
{
|
||||
if (++(*vi_) == object_->value_.array->end())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (json::value_t::object):
|
||||
{
|
||||
if (++(*oi_) == object_->value_.object->end())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
json& json::iterator::operator*() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::runtime_error("cannot get value");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
|
@ -2085,10 +2050,9 @@ json& json::iterator::operator*() const
|
|||
|
||||
json* json::iterator::operator->() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::runtime_error("cannot get value");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
|
@ -2110,20 +2074,17 @@ json* json::iterator::operator->() const
|
|||
|
||||
std::string json::iterator::key() const
|
||||
{
|
||||
if (object_ != nullptr and object_->type_ == json::value_t::object)
|
||||
if (object_ == nullptr or invalid or object_->type_ != json::value_t::object)
|
||||
{
|
||||
return (*oi_)->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::out_of_range("cannot get key");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
return (*oi_)->first;
|
||||
}
|
||||
|
||||
json& json::iterator::value() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
@ -2146,90 +2107,61 @@ json& json::iterator::value() const
|
|||
}
|
||||
|
||||
|
||||
json::const_iterator::const_iterator(const json* j) : object_(j)
|
||||
json::const_iterator::const_iterator(const json* j, bool begin)
|
||||
: object_(j), invalid(not begin or j == nullptr)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
if (begin)
|
||||
{
|
||||
object_ = nullptr;
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->cbegin());
|
||||
invalid = (*vi_ == object_->value_.array->cend());
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->begin());
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->cend());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
if (begin)
|
||||
{
|
||||
object_ = nullptr;
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->cbegin());
|
||||
invalid = (*oi_ == object_->value_.object->cend());
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->begin());
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->cend());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.object_)
|
||||
json::const_iterator::const_iterator(const json::const_iterator& o)
|
||||
: object_(o.object_), invalid(o.invalid)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
if (o.vi_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->begin());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->begin());
|
||||
}
|
||||
}
|
||||
vi_ = new array_t::const_iterator(*(o.vi_));
|
||||
}
|
||||
if (o.oi_ != nullptr)
|
||||
{
|
||||
oi_ = new object_t::const_iterator(*(o.oi_));
|
||||
}
|
||||
}
|
||||
|
||||
json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object_)
|
||||
json::const_iterator::const_iterator(const json::iterator& o)
|
||||
: object_(o.object_), invalid(o.invalid)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
if (o.vi_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->begin());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->begin());
|
||||
}
|
||||
}
|
||||
vi_ = new array_t::const_iterator(*(o.vi_));
|
||||
}
|
||||
if (o.oi_ != nullptr)
|
||||
{
|
||||
oi_ = new object_t::const_iterator(*(o.oi_));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2244,29 +2176,29 @@ json::const_iterator& json::const_iterator::operator=(json::const_iterator o)
|
|||
std::swap(object_, o.object_);
|
||||
std::swap(vi_, o.vi_);
|
||||
std::swap(oi_, o.oi_);
|
||||
std::swap(invalid, o.invalid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool json::const_iterator::operator==(const json::const_iterator& o) const
|
||||
{
|
||||
if (object_ != o.object_)
|
||||
if (object_ != nullptr and o.object_ != nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
if (object_->type_ == json::value_t::array and o.object_->type_ == json::value_t::array)
|
||||
{
|
||||
return (vi_ == o.vi_);
|
||||
return (*vi_ == *(o.vi_));
|
||||
}
|
||||
if (object_->type_ == json::value_t::object)
|
||||
if (object_->type_ == json::value_t::object and o.object_->type_ == json::value_t::object)
|
||||
{
|
||||
return (oi_ == o.oi_);
|
||||
return (*oi_ == *(o.oi_));
|
||||
}
|
||||
if (invalid == o.invalid and object_ == o.object_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool json::const_iterator::operator!=(const json::const_iterator& o) const
|
||||
|
@ -2276,44 +2208,38 @@ bool json::const_iterator::operator!=(const json::const_iterator& o) const
|
|||
|
||||
json::const_iterator& json::const_iterator::operator++()
|
||||
{
|
||||
// iterator cannot be incremented
|
||||
if (object_ == nullptr)
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
return *this;
|
||||
switch (object_->type_)
|
||||
{
|
||||
case (json::value_t::array):
|
||||
{
|
||||
std::advance(*vi_, 1);
|
||||
invalid = (*vi_ == object_->value_.array->end());
|
||||
break;
|
||||
}
|
||||
case (json::value_t::object):
|
||||
{
|
||||
std::advance(*oi_, 1);
|
||||
invalid = (*oi_ == object_->value_.object->end());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
{
|
||||
case (json::value_t::array):
|
||||
{
|
||||
if (++(*vi_) == object_->value_.array->end())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (json::value_t::object):
|
||||
{
|
||||
if (++(*oi_) == object_->value_.object->end())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const json& json::const_iterator::operator*() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::runtime_error("cannot get value");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
|
@ -2335,10 +2261,9 @@ const json& json::const_iterator::operator*() const
|
|||
|
||||
const json* json::const_iterator::operator->() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::runtime_error("cannot get value");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
|
@ -2360,20 +2285,17 @@ const json* json::const_iterator::operator->() const
|
|||
|
||||
std::string json::const_iterator::key() const
|
||||
{
|
||||
if (object_ != nullptr and object_->type_ == json::value_t::object)
|
||||
if (object_ == nullptr or invalid or object_->type_ != json::value_t::object)
|
||||
{
|
||||
return (*oi_)->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::out_of_range("cannot get key");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
return (*oi_)->first;
|
||||
}
|
||||
|
||||
const json& json::const_iterator::value() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
|
379
src/json.cc
379
src/json.cc
|
@ -1245,50 +1245,28 @@ json::const_iterator json::find(const std::string& key) const
|
|||
|
||||
json::iterator json::find(const char* key)
|
||||
{
|
||||
if (type_ != value_t::object)
|
||||
auto result = end();
|
||||
|
||||
if (type_ == value_t::object)
|
||||
{
|
||||
return end();
|
||||
}
|
||||
else
|
||||
{
|
||||
const object_t::iterator i = value_.object->find(key);
|
||||
if (i != value_.object->end())
|
||||
{
|
||||
json::iterator result(this);
|
||||
delete result.oi_;
|
||||
result.oi_ = nullptr;
|
||||
result.oi_ = new object_t::iterator(i);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return end();
|
||||
}
|
||||
result.oi_ = new object_t::iterator(value_.object->find(key));
|
||||
result.invalid = (*(result.oi_) == value_.object->end());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
json::const_iterator json::find(const char* key) const
|
||||
{
|
||||
if (type_ != value_t::object)
|
||||
auto result = cend();
|
||||
|
||||
if (type_ == value_t::object)
|
||||
{
|
||||
return end();
|
||||
}
|
||||
else
|
||||
{
|
||||
const object_t::const_iterator i = value_.object->find(key);
|
||||
if (i != value_.object->end())
|
||||
{
|
||||
json::const_iterator result(this);
|
||||
delete result.oi_;
|
||||
result.oi_ = nullptr;
|
||||
result.oi_ = new object_t::const_iterator(i);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
return end();
|
||||
}
|
||||
result.oi_ = new object_t::const_iterator(value_.object->find(key));
|
||||
result.invalid = (*(result.oi_) == value_.object->cend());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool json::operator==(const json& o) const noexcept
|
||||
|
@ -1372,90 +1350,78 @@ bool json::operator!=(const json& o) const noexcept
|
|||
|
||||
json::iterator json::begin() noexcept
|
||||
{
|
||||
return json::iterator(this);
|
||||
return json::iterator(this, true);
|
||||
}
|
||||
|
||||
json::iterator json::end() noexcept
|
||||
{
|
||||
return json::iterator();
|
||||
return json::iterator(this, false);
|
||||
}
|
||||
|
||||
json::const_iterator json::begin() const noexcept
|
||||
{
|
||||
return json::const_iterator(this);
|
||||
return json::const_iterator(this, true);
|
||||
}
|
||||
|
||||
json::const_iterator json::end() const noexcept
|
||||
{
|
||||
return json::const_iterator();
|
||||
return json::const_iterator(this, false);
|
||||
}
|
||||
|
||||
json::const_iterator json::cbegin() const noexcept
|
||||
{
|
||||
return json::const_iterator(this);
|
||||
return json::const_iterator(this, true);
|
||||
}
|
||||
|
||||
json::const_iterator json::cend() const noexcept
|
||||
{
|
||||
return json::const_iterator();
|
||||
return json::const_iterator(this, false);
|
||||
}
|
||||
|
||||
|
||||
json::iterator::iterator(json* j) : object_(j)
|
||||
json::iterator::iterator(json* j, bool begin)
|
||||
: object_(j), invalid(not begin or j == nullptr)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
if (begin)
|
||||
{
|
||||
object_ = nullptr;
|
||||
vi_ = new array_t::iterator(object_->value_.array->begin());
|
||||
invalid = (*vi_ == object_->value_.array->end());
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::iterator(object_->value_.array->begin());
|
||||
vi_ = new array_t::iterator(object_->value_.array->end());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
if (begin)
|
||||
{
|
||||
object_ = nullptr;
|
||||
oi_ = new object_t::iterator(object_->value_.object->begin());
|
||||
invalid = (*oi_ == object_->value_.object->end());
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::iterator(object_->value_.object->begin());
|
||||
oi_ = new object_t::iterator(object_->value_.object->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json::iterator::iterator(const json::iterator& o) : object_(o.object_)
|
||||
json::iterator::iterator(const json::iterator& o)
|
||||
: object_(o.object_), invalid(o.invalid)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
if (o.vi_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::iterator(object_->value_.array->begin());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::iterator(object_->value_.object->begin());
|
||||
}
|
||||
}
|
||||
vi_ = new array_t::iterator(*(o.vi_));
|
||||
}
|
||||
|
||||
if (o.oi_ != nullptr)
|
||||
{
|
||||
oi_ = new object_t::iterator(*(o.oi_));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1470,29 +1436,29 @@ json::iterator& json::iterator::operator=(json::iterator o)
|
|||
std::swap(object_, o.object_);
|
||||
std::swap(vi_, o.vi_);
|
||||
std::swap(oi_, o.oi_);
|
||||
std::swap(invalid, o.invalid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool json::iterator::operator==(const json::iterator& o) const
|
||||
{
|
||||
if (object_ != o.object_)
|
||||
if (object_ != nullptr and o.object_ != nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
if (object_->type_ == json::value_t::array and o.object_->type_ == json::value_t::array)
|
||||
{
|
||||
return (vi_ == o.vi_);
|
||||
return (*vi_ == *(o.vi_));
|
||||
}
|
||||
if (object_->type_ == json::value_t::object)
|
||||
if (object_->type_ == json::value_t::object and o.object_->type_ == json::value_t::object)
|
||||
{
|
||||
return (oi_ == o.oi_);
|
||||
return (*oi_ == *(o.oi_));
|
||||
}
|
||||
|
||||
if (invalid == o.invalid and object_ == o.object_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool json::iterator::operator!=(const json::iterator& o) const
|
||||
|
@ -1502,44 +1468,38 @@ bool json::iterator::operator!=(const json::iterator& o) const
|
|||
|
||||
json::iterator& json::iterator::operator++()
|
||||
{
|
||||
// iterator cannot be incremented
|
||||
if (object_ == nullptr)
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
return *this;
|
||||
switch (object_->type_)
|
||||
{
|
||||
case (json::value_t::array):
|
||||
{
|
||||
std::advance(*vi_, 1);
|
||||
invalid = (*vi_ == object_->value_.array->end());
|
||||
break;
|
||||
}
|
||||
case (json::value_t::object):
|
||||
{
|
||||
std::advance(*oi_, 1);
|
||||
invalid = (*oi_ == object_->value_.object->end());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
{
|
||||
case (json::value_t::array):
|
||||
{
|
||||
if (++(*vi_) == object_->value_.array->end())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (json::value_t::object):
|
||||
{
|
||||
if (++(*oi_) == object_->value_.object->end())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
json& json::iterator::operator*() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::runtime_error("cannot get value");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
|
@ -1561,10 +1521,9 @@ json& json::iterator::operator*() const
|
|||
|
||||
json* json::iterator::operator->() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::runtime_error("cannot get value");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
|
@ -1586,20 +1545,17 @@ json* json::iterator::operator->() const
|
|||
|
||||
std::string json::iterator::key() const
|
||||
{
|
||||
if (object_ != nullptr and object_->type_ == json::value_t::object)
|
||||
if (object_ == nullptr or invalid or object_->type_ != json::value_t::object)
|
||||
{
|
||||
return (*oi_)->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::out_of_range("cannot get key");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
return (*oi_)->first;
|
||||
}
|
||||
|
||||
json& json::iterator::value() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
@ -1622,90 +1578,61 @@ json& json::iterator::value() const
|
|||
}
|
||||
|
||||
|
||||
json::const_iterator::const_iterator(const json* j) : object_(j)
|
||||
json::const_iterator::const_iterator(const json* j, bool begin)
|
||||
: object_(j), invalid(not begin or j == nullptr)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
if (begin)
|
||||
{
|
||||
object_ = nullptr;
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->cbegin());
|
||||
invalid = (*vi_ == object_->value_.array->cend());
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->begin());
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->cend());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
if (begin)
|
||||
{
|
||||
object_ = nullptr;
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->cbegin());
|
||||
invalid = (*oi_ == object_->value_.object->cend());
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->begin());
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->cend());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json::const_iterator::const_iterator(const json::const_iterator& o) : object_(o.object_)
|
||||
json::const_iterator::const_iterator(const json::const_iterator& o)
|
||||
: object_(o.object_), invalid(o.invalid)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
if (o.vi_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->begin());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->begin());
|
||||
}
|
||||
}
|
||||
vi_ = new array_t::const_iterator(*(o.vi_));
|
||||
}
|
||||
if (o.oi_ != nullptr)
|
||||
{
|
||||
oi_ = new object_t::const_iterator(*(o.oi_));
|
||||
}
|
||||
}
|
||||
|
||||
json::const_iterator::const_iterator(const json::iterator& o) : object_(o.object_)
|
||||
json::const_iterator::const_iterator(const json::iterator& o)
|
||||
: object_(o.object_), invalid(o.invalid)
|
||||
{
|
||||
if (object_ != nullptr)
|
||||
if (o.vi_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
vi_ = new array_t::const_iterator(object_->value_.array->begin());
|
||||
}
|
||||
}
|
||||
else if (object_->type_ == json::value_t::object)
|
||||
{
|
||||
if (object_->empty())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
oi_ = new object_t::const_iterator(object_->value_.object->begin());
|
||||
}
|
||||
}
|
||||
vi_ = new array_t::const_iterator(*(o.vi_));
|
||||
}
|
||||
if (o.oi_ != nullptr)
|
||||
{
|
||||
oi_ = new object_t::const_iterator(*(o.oi_));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1720,29 +1647,29 @@ json::const_iterator& json::const_iterator::operator=(json::const_iterator o)
|
|||
std::swap(object_, o.object_);
|
||||
std::swap(vi_, o.vi_);
|
||||
std::swap(oi_, o.oi_);
|
||||
std::swap(invalid, o.invalid);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool json::const_iterator::operator==(const json::const_iterator& o) const
|
||||
{
|
||||
if (object_ != o.object_)
|
||||
if (object_ != nullptr and o.object_ != nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
if (object_->type_ == json::value_t::array)
|
||||
if (object_->type_ == json::value_t::array and o.object_->type_ == json::value_t::array)
|
||||
{
|
||||
return (vi_ == o.vi_);
|
||||
return (*vi_ == *(o.vi_));
|
||||
}
|
||||
if (object_->type_ == json::value_t::object)
|
||||
if (object_->type_ == json::value_t::object and o.object_->type_ == json::value_t::object)
|
||||
{
|
||||
return (oi_ == o.oi_);
|
||||
return (*oi_ == *(o.oi_));
|
||||
}
|
||||
if (invalid == o.invalid and object_ == o.object_)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool json::const_iterator::operator!=(const json::const_iterator& o) const
|
||||
|
@ -1752,44 +1679,38 @@ bool json::const_iterator::operator!=(const json::const_iterator& o) const
|
|||
|
||||
json::const_iterator& json::const_iterator::operator++()
|
||||
{
|
||||
// iterator cannot be incremented
|
||||
if (object_ == nullptr)
|
||||
if (object_ != nullptr)
|
||||
{
|
||||
return *this;
|
||||
switch (object_->type_)
|
||||
{
|
||||
case (json::value_t::array):
|
||||
{
|
||||
std::advance(*vi_, 1);
|
||||
invalid = (*vi_ == object_->value_.array->end());
|
||||
break;
|
||||
}
|
||||
case (json::value_t::object):
|
||||
{
|
||||
std::advance(*oi_, 1);
|
||||
invalid = (*oi_ == object_->value_.object->end());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
invalid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
{
|
||||
case (json::value_t::array):
|
||||
{
|
||||
if (++(*vi_) == object_->value_.array->end())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case (json::value_t::object):
|
||||
{
|
||||
if (++(*oi_) == object_->value_.object->end())
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
object_ = nullptr;
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
const json& json::const_iterator::operator*() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::runtime_error("cannot get value");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
|
@ -1811,10 +1732,9 @@ const json& json::const_iterator::operator*() const
|
|||
|
||||
const json* json::const_iterator::operator->() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::runtime_error("cannot get value");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
switch (object_->type_)
|
||||
|
@ -1836,20 +1756,17 @@ const json* json::const_iterator::operator->() const
|
|||
|
||||
std::string json::const_iterator::key() const
|
||||
{
|
||||
if (object_ != nullptr and object_->type_ == json::value_t::object)
|
||||
if (object_ == nullptr or invalid or object_->type_ != json::value_t::object)
|
||||
{
|
||||
return (*oi_)->first;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::out_of_range("cannot get key");
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
||||
return (*oi_)->first;
|
||||
}
|
||||
|
||||
const json& json::const_iterator::value() const
|
||||
{
|
||||
// dereferencing end() is an error
|
||||
if (object_ == nullptr)
|
||||
if (object_ == nullptr or invalid)
|
||||
{
|
||||
throw std::out_of_range("cannot get value");
|
||||
}
|
||||
|
|
17
src/json.h
17
src/json.h
|
@ -42,11 +42,12 @@ due to alignment.
|
|||
*/
|
||||
class json
|
||||
{
|
||||
public:
|
||||
private:
|
||||
// forward declaration to friend this class
|
||||
class iterator;
|
||||
class const_iterator;
|
||||
|
||||
public:
|
||||
// container types
|
||||
using value_type = json;
|
||||
using reference = json&;
|
||||
|
@ -371,15 +372,15 @@ class json
|
|||
/// the payload
|
||||
value value_ {};
|
||||
|
||||
public:
|
||||
private:
|
||||
/// an iterator
|
||||
class iterator : public std::iterator<std::forward_iterator_tag, json>
|
||||
class iterator : private std::iterator<std::forward_iterator_tag, json>
|
||||
{
|
||||
friend class json;
|
||||
friend class json::const_iterator;
|
||||
public:
|
||||
iterator() = default;
|
||||
iterator(json*);
|
||||
iterator(json*, bool);
|
||||
iterator(const iterator&);
|
||||
~iterator();
|
||||
|
||||
|
@ -402,16 +403,18 @@ class json
|
|||
array_t::iterator* vi_ = nullptr;
|
||||
/// an iterator for JSON objects
|
||||
object_t::iterator* oi_ = nullptr;
|
||||
/// whether iterator points to a valid object
|
||||
bool invalid = true;
|
||||
};
|
||||
|
||||
/// a const iterator
|
||||
class const_iterator : public std::iterator<std::forward_iterator_tag, const json>
|
||||
class const_iterator : private std::iterator<std::forward_iterator_tag, const json>
|
||||
{
|
||||
friend class json;
|
||||
|
||||
public:
|
||||
const_iterator() = default;
|
||||
const_iterator(const json*);
|
||||
const_iterator(const json*, bool);
|
||||
const_iterator(const const_iterator&);
|
||||
const_iterator(const json::iterator&);
|
||||
~const_iterator();
|
||||
|
@ -435,6 +438,8 @@ class json
|
|||
array_t::const_iterator* vi_ = nullptr;
|
||||
/// an iterator for JSON objects
|
||||
object_t::const_iterator* oi_ = nullptr;
|
||||
/// whether iterator reached past the end
|
||||
bool invalid = true;
|
||||
};
|
||||
|
||||
private:
|
||||
|
|
|
@ -1371,35 +1371,35 @@ TEST_CASE("Iterators")
|
|||
CHECK(* j7.begin() == json("hello"));
|
||||
CHECK(* j7_const.begin() == json("hello"));
|
||||
|
||||
CHECK_THROWS_AS(* j1.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j1.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j2.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j2.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j3.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j3.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j4.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j4.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j5.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j5.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j6.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j6.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j7.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j7.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j1.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j1.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j2.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j2.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j3.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j3.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j4.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j4.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j5.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j5.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j6.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j6.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j7.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j7.cend(), std::out_of_range);
|
||||
|
||||
CHECK_THROWS_AS(* j1_const.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j1_const.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j2_const.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j2_const.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j3_const.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j3_const.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j4_const.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j4_const.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j5_const.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j5_const.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j6_const.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j6_const.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j7_const.end(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j7_const.cend(), std::runtime_error);
|
||||
CHECK_THROWS_AS(* j1_const.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j1_const.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j2_const.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j2_const.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j3_const.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j3_const.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j4_const.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j4_const.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j5_const.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j5_const.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j6_const.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j6_const.cend(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j7_const.end(), std::out_of_range);
|
||||
CHECK_THROWS_AS(* j7_const.cend(), std::out_of_range);
|
||||
|
||||
// operator ->
|
||||
CHECK(j1.begin()->type() == json::value_t::number);
|
||||
|
@ -1432,35 +1432,35 @@ TEST_CASE("Iterators")
|
|||
CHECK(j7_const.begin()->type() == json::value_t::string);
|
||||
CHECK(j7_const.cbegin()->type() == json::value_t::string);
|
||||
|
||||
CHECK_THROWS_AS(j1.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j1.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j2.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j2.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j3.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j3.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j4.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j4.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j5.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j5.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j6.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j6.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j7.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j7.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j1.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j1.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j2.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j2.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j3.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j3.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j4.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j4.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j5.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j5.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j6.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j6.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j7.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j7.cend()->type(), std::out_of_range);
|
||||
|
||||
CHECK_THROWS_AS(j1_const.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j1_const.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j2_const.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j2_const.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j3_const.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j3_const.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j4_const.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j4_const.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j5_const.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j5_const.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j6_const.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j6_const.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j7_const.end()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j7_const.cend()->type(), std::runtime_error);
|
||||
CHECK_THROWS_AS(j1_const.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j1_const.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j2_const.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j2_const.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j3_const.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j3_const.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j4_const.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j4_const.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j5_const.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j5_const.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j6_const.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j6_const.cend()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j7_const.end()->type(), std::out_of_range);
|
||||
CHECK_THROWS_AS(j7_const.cend()->type(), std::out_of_range);
|
||||
|
||||
// value
|
||||
CHECK(j1.begin().value().type() == json::value_t::number);
|
||||
|
|
Loading…
Reference in a new issue