Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
5c813b61
Commit
5c813b61
authored
Jul 14, 2015
by
Niels
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
closes #104 and integrates code from #93
Iterators are now implemented via const_iterators and reverse_iterator and const_reverse_iterator now share a template class. Thanks a lot!
parent
1c8d5dc2
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
263 additions
and
1253 deletions
+263
-1253
Makefile
doc/Makefile
+1
-1
json.hpp
src/json.hpp
+131
-626
json.hpp.re2c
src/json.hpp.re2c
+131
-626
No files found.
doc/Makefile
View file @
5c813b61
...
@@ -54,7 +54,7 @@ doxygen: create_output create_links
...
@@ -54,7 +54,7 @@ doxygen: create_output create_links
gsed
-i
's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g'
html/
*
.html
gsed
-i
's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g'
html/
*
.html
gsed
-i
's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g'
html/
*
.html
gsed
-i
's@< ObjectType, ArrayType, StringType, BooleanType, NumberIntegerType, NumberFloatType, AllocatorType >@@g'
html/
*
.html
upload
:
doxygen check_output
upload
:
clean
doxygen check_output
cd
html
;
../git-update-ghpages nlohmann/json
cd
html
;
../git-update-ghpages nlohmann/json
rm
-fr
html
rm
-fr
html
open http://nlohmann.github.io/json/
open http://nlohmann.github.io/json/
...
...
src/json.hpp
View file @
5c813b61
...
@@ -172,14 +172,17 @@ class basic_json
...
@@ -172,14 +172,17 @@ class basic_json
/// the type of an element const pointer
/// the type of an element const pointer
using
const_pointer
=
typename
std
::
allocator_traits
<
allocator_type
>::
const_pointer
;
using
const_pointer
=
typename
std
::
allocator_traits
<
allocator_type
>::
const_pointer
;
// forward declaration
template
<
typename
Base
>
class
json_reverse_iterator
;
/// an iterator for a basic_json container
/// an iterator for a basic_json container
class
iterator
;
class
iterator
;
/// a const iterator for a basic_json container
/// a const iterator for a basic_json container
class
const_iterator
;
class
const_iterator
;
/// a reverse iterator for a basic_json container
/// a reverse iterator for a basic_json container
class
reverse_iterator
;
using
reverse_iterator
=
json_reverse_iterator
<
typename
basic_json
::
iterator
>
;
/// a const reverse iterator for a basic_json container
/// a const reverse iterator for a basic_json container
class
const_reverse_iterator
;
using
const_reverse_iterator
=
json_reverse_iterator
<
typename
basic_json
::
const_iterator
>
;
/// @}
/// @}
...
@@ -4863,8 +4866,8 @@ class basic_json
...
@@ -4863,8 +4866,8 @@ class basic_json
};
};
public
:
public
:
/// a random access iterator for the basic_json class
/// a
const
random access iterator for the basic_json class
class
iterator
:
public
std
::
iterator
<
std
::
random_access_iterator_tag
,
basic_json
>
class
const_iterator
:
public
std
::
iterator
<
std
::
random_access_iterator_tag
,
const
basic_json
>
{
{
// allow basic_json class to access m_it
// allow basic_json class to access m_it
friend
class
basic_json
;
friend
class
basic_json
;
...
@@ -4875,17 +4878,17 @@ class basic_json
...
@@ -4875,17 +4878,17 @@ class basic_json
/// a type to represent differences between iterators
/// a type to represent differences between iterators
using
difference_type
=
typename
basic_json
::
difference_type
;
using
difference_type
=
typename
basic_json
::
difference_type
;
/// defines a pointer to the type iterated over (value_type)
/// defines a pointer to the type iterated over (value_type)
using
pointer
=
typename
basic_json
::
pointer
;
using
pointer
=
typename
basic_json
::
const_
pointer
;
/// defines a reference to the type iterated over (value_type)
/// defines a reference to the type iterated over (value_type)
using
reference
=
typename
basic_json
::
reference
;
using
reference
=
typename
basic_json
::
const_
reference
;
/// the category of the iterator
/// the category of the iterator
using
iterator_category
=
std
::
bidirectional_iterator_tag
;
using
iterator_category
=
std
::
bidirectional_iterator_tag
;
/// default constructor
/// default constructor
iterator
()
=
default
;
const_
iterator
()
=
default
;
/// constructor for a given JSON instance
/// constructor for a given JSON instance
iterator
(
pointer
object
)
:
m_object
(
object
)
const_
iterator
(
pointer
object
)
:
m_object
(
object
)
{
{
switch
(
m_object
->
m_type
)
switch
(
m_object
->
m_type
)
{
{
...
@@ -4907,13 +4910,38 @@ class basic_json
...
@@ -4907,13 +4910,38 @@ class basic_json
}
}
}
}
/// copy constructor given a nonconst iterator
const_iterator
(
const
iterator
&
other
)
:
m_object
(
other
.
m_object
)
{
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
m_it
.
object_iterator
=
other
.
m_it
.
object_iterator
;
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
m_it
.
array_iterator
=
other
.
m_it
.
array_iterator
;
break
;
}
default
:
{
m_it
.
primitive_iterator
=
other
.
m_it
.
primitive_iterator
;
break
;
}
}
}
/// copy constructor
/// copy constructor
iterator
(
const
iterator
&
other
)
noexcept
const_iterator
(
const
const_
iterator
&
other
)
noexcept
:
m_object
(
other
.
m_object
),
m_it
(
other
.
m_it
)
:
m_object
(
other
.
m_object
),
m_it
(
other
.
m_it
)
{}
{}
/// copy assignment
/// copy assignment
iterator
&
operator
=
(
iterator
other
)
noexcept
(
const_iterator
&
operator
=
(
const_iterator
other
)
noexcept
(
std
::
is_nothrow_move_constructible
<
pointer
>::
value
and
std
::
is_nothrow_move_constructible
<
pointer
>::
value
and
std
::
is_nothrow_move_assignable
<
pointer
>::
value
and
std
::
is_nothrow_move_assignable
<
pointer
>::
value
and
std
::
is_nothrow_move_constructible
<
internal_iterator
>::
value
and
std
::
is_nothrow_move_constructible
<
internal_iterator
>::
value
and
...
@@ -4985,7 +5013,7 @@ class basic_json
...
@@ -4985,7 +5013,7 @@ class basic_json
public
:
public
:
/// return a reference to the value pointed to by the iterator
/// return a reference to the value pointed to by the iterator
reference
operator
*
()
reference
operator
*
()
const
{
{
switch
(
m_object
->
m_type
)
switch
(
m_object
->
m_type
)
{
{
...
@@ -5019,7 +5047,7 @@ class basic_json
...
@@ -5019,7 +5047,7 @@ class basic_json
}
}
/// dereference the iterator
/// dereference the iterator
pointer
operator
->
()
pointer
operator
->
()
const
{
{
switch
(
m_object
->
m_type
)
switch
(
m_object
->
m_type
)
{
{
...
@@ -5033,11 +5061,6 @@ class basic_json
...
@@ -5033,11 +5061,6 @@ class basic_json
return
&*
m_it
.
array_iterator
;
return
&*
m_it
.
array_iterator
;
}
}
case
(
basic_json
:
:
value_t
::
null
)
:
{
throw
std
::
out_of_range
(
"cannot get value"
);
}
default
:
default
:
{
{
if
(
m_it
.
primitive_iterator
.
is_begin
())
if
(
m_it
.
primitive_iterator
.
is_begin
())
...
@@ -5053,36 +5076,16 @@ class basic_json
...
@@ -5053,36 +5076,16 @@ class basic_json
}
}
/// post-increment (it++)
/// post-increment (it++)
iterator
operator
++
(
int
)
const_
iterator
operator
++
(
int
)
{
{
auto
result
=
*
this
;
auto
result
=
*
this
;
++
(
*
this
);
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
m_it
.
object_iterator
++
;
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
m_it
.
array_iterator
++
;
break
;
}
default
:
{
m_it
.
primitive_iterator
++
;
break
;
}
}
return
result
;
return
result
;
}
}
/// pre-increment (++it)
/// pre-increment (++it)
iterator
&
operator
++
()
const_
iterator
&
operator
++
()
{
{
switch
(
m_object
->
m_type
)
switch
(
m_object
->
m_type
)
{
{
...
@@ -5109,36 +5112,16 @@ class basic_json
...
@@ -5109,36 +5112,16 @@ class basic_json
}
}
/// post-decrement (it--)
/// post-decrement (it--)
iterator
operator
--
(
int
)
const_
iterator
operator
--
(
int
)
{
{
auto
result
=
*
this
;
auto
result
=
*
this
;
--
(
*
this
);
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
m_it
.
object_iterator
--
;
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
m_it
.
array_iterator
--
;
break
;
}
default
:
{
m_it
.
primitive_iterator
--
;
break
;
}
}
return
result
;
return
result
;
}
}
/// pre-decrement (--it)
/// pre-decrement (--it)
iterator
&
operator
--
()
const_
iterator
&
operator
--
()
{
{
switch
(
m_object
->
m_type
)
switch
(
m_object
->
m_type
)
{
{
...
@@ -5165,7 +5148,7 @@ class basic_json
...
@@ -5165,7 +5148,7 @@ class basic_json
}
}
/// comparison: equal
/// comparison: equal
bool
operator
==
(
const
iterator
&
other
)
const
bool
operator
==
(
const
const_
iterator
&
other
)
const
{
{
// if objects are not the same, the comparison is undefined
// if objects are not the same, the comparison is undefined
if
(
m_object
!=
other
.
m_object
)
if
(
m_object
!=
other
.
m_object
)
...
@@ -5193,13 +5176,13 @@ class basic_json
...
@@ -5193,13 +5176,13 @@ class basic_json
}
}
/// comparison: not equal
/// comparison: not equal
bool
operator
!=
(
const
iterator
&
other
)
const
bool
operator
!=
(
const
const_
iterator
&
other
)
const
{
{
return
not
operator
==
(
other
);
return
not
operator
==
(
other
);
}
}
/// comparison: smaller
/// comparison: smaller
bool
operator
<
(
const
iterator
&
other
)
const
bool
operator
<
(
const
const_
iterator
&
other
)
const
{
{
// if objects are not the same, the comparison is undefined
// if objects are not the same, the comparison is undefined
if
(
m_object
!=
other
.
m_object
)
if
(
m_object
!=
other
.
m_object
)
...
@@ -5227,25 +5210,25 @@ class basic_json
...
@@ -5227,25 +5210,25 @@ class basic_json
}
}
/// comparison: less than or equal
/// comparison: less than or equal
bool
operator
<=
(
const
iterator
&
other
)
const
bool
operator
<=
(
const
const_
iterator
&
other
)
const
{
{
return
not
other
.
operator
<
(
*
this
);
return
not
other
.
operator
<
(
*
this
);
}
}
/// comparison: greater than
/// comparison: greater than
bool
operator
>
(
const
iterator
&
other
)
const
bool
operator
>
(
const
const_
iterator
&
other
)
const
{
{
return
not
operator
<=
(
other
);
return
not
operator
<=
(
other
);
}
}
/// comparison: greater than or equal
/// comparison: greater than or equal
bool
operator
>=
(
const
iterator
&
other
)
const
bool
operator
>=
(
const
const_
iterator
&
other
)
const
{
{
return
not
operator
<
(
other
);
return
not
operator
<
(
other
);
}
}
/// add to iterator
/// add to iterator
iterator
&
operator
+=
(
difference_type
i
)
const_
iterator
&
operator
+=
(
difference_type
i
)
{
{
switch
(
m_object
->
m_type
)
switch
(
m_object
->
m_type
)
{
{
...
@@ -5271,13 +5254,13 @@ class basic_json
...
@@ -5271,13 +5254,13 @@ class basic_json
}
}
/// subtract from iterator
/// subtract from iterator
iterator
&
operator
-=
(
difference_type
i
)
const_
iterator
&
operator
-=
(
difference_type
i
)
{
{
return
operator
+=
(
-
i
);
return
operator
+=
(
-
i
);
}
}
/// add to iterator
/// add to iterator
iterator
operator
+
(
difference_type
i
)
const_
iterator
operator
+
(
difference_type
i
)
{
{
auto
result
=
*
this
;
auto
result
=
*
this
;
result
+=
i
;
result
+=
i
;
...
@@ -5285,7 +5268,7 @@ class basic_json
...
@@ -5285,7 +5268,7 @@ class basic_json
}
}
/// subtract from iterator
/// subtract from iterator
iterator
operator
-
(
difference_type
i
)
const_
iterator
operator
-
(
difference_type
i
)
{
{
auto
result
=
*
this
;
auto
result
=
*
this
;
result
-=
i
;
result
-=
i
;
...
@@ -5293,14 +5276,13 @@ class basic_json
...
@@ -5293,14 +5276,13 @@ class basic_json
}
}
/// return difference
/// return difference
difference_type
operator
-
(
const
iterator
&
other
)
const
difference_type
operator
-
(
const
const_
iterator
&
other
)
const
{
{
switch
(
m_object
->
m_type
)
switch
(
m_object
->
m_type
)
{
{
case
(
basic_json
:
:
value_t
::
object
)
:
case
(
basic_json
:
:
value_t
::
object
)
:
{
{
throw
std
::
domain_error
(
"cannot use operator- for object iterators"
);
throw
std
::
domain_error
(
"cannot use operator- for object iterators"
);
return
0
;
}
}
case
(
basic_json
:
:
value_t
::
array
)
:
case
(
basic_json
:
:
value_t
::
array
)
:
...
@@ -5316,7 +5298,7 @@ class basic_json
...
@@ -5316,7 +5298,7 @@ class basic_json
}
}
/// access to successor
/// access to successor
reference
operator
[](
difference_type
n
)
reference
operator
[](
difference_type
n
)
const
{
{
switch
(
m_object
->
m_type
)
switch
(
m_object
->
m_type
)
{
{
...
@@ -5366,8 +5348,8 @@ class basic_json
...
@@ -5366,8 +5348,8 @@ class basic_json
}
}
}
}
/// return the
key
of an iterator
/// return the
value
of an iterator
reference
value
()
reference
value
()
const
{
{
return
operator
*
();
return
operator
*
();
}
}
...
@@ -5379,401 +5361,96 @@ class basic_json
...
@@ -5379,401 +5361,96 @@ class basic_json
internal_iterator
m_it
=
internal_iterator
();
internal_iterator
m_it
=
internal_iterator
();
};
};
/// a
const
random access iterator for the basic_json class
/// a random access iterator for the basic_json class
class
const_iterator
:
public
std
::
iterator
<
std
::
random_access_iterator_tag
,
const
basic_json
>
class
iterator
:
public
const_iterator
{
{
// allow basic_json class to access m_it
friend
class
basic_json
;
public
:
public
:
/// the type of the values when the iterator is dereferenced
using
base_iterator
=
const_iterator
;
using
value_type
=
typename
basic_json
::
value_type
;
using
pointer
=
typename
basic_json
::
pointer
;
/// a type to represent differences between iterators
using
reference
=
typename
basic_json
::
reference
;
using
difference_type
=
typename
basic_json
::
difference_type
;
/// defines a pointer to the type iterated over (value_type)
using
pointer
=
typename
basic_json
::
const_pointer
;
/// defines a reference to the type iterated over (value_type)
using
reference
=
typename
basic_json
::
const_reference
;
/// the category of the iterator
using
iterator_category
=
std
::
bidirectional_iterator_tag
;
/// default constructor
/// default constructor
const_
iterator
()
=
default
;
iterator
()
=
default
;
/// constructor for a given JSON instance
/// constructor for a given JSON instance
const_iterator
(
pointer
object
)
:
m_object
(
object
)
iterator
(
pointer
object
)
noexcept
:
base_iterator
(
object
)
{
{}
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
m_it
.
object_iterator
=
typename
object_t
::
iterator
();
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
m_it
.
array_iterator
=
typename
array_t
::
iterator
();
break
;
}
default
:
{
m_it
.
primitive_iterator
=
primitive_iterator_t
();
break
;
}
}
}
/// copy constructor given a nonconst iterator
const_iterator
(
const
iterator
&
other
)
:
m_object
(
other
.
m_object
)
{
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
m_it
.
object_iterator
=
other
.
m_it
.
object_iterator
;
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
m_it
.
array_iterator
=
other
.
m_it
.
array_iterator
;
break
;
}
default
:
{
m_it
.
primitive_iterator
=
other
.
m_it
.
primitive_iterator
;
break
;
}
}
}
/// copy constructor
/// copy constructor
const_iterator
(
const
const_
iterator
&
other
)
noexcept
iterator
(
const
iterator
&
other
)
noexcept
:
m_object
(
other
.
m_object
),
m_it
(
other
.
m_it
)
:
base_iterator
(
other
)
{}
{}
/// copy assignment
/// copy assignment
const_iterator
&
operator
=
(
const_
iterator
other
)
noexcept
(
iterator
&
operator
=
(
iterator
other
)
noexcept
(
std
::
is_nothrow_move_constructible
<
pointer
>::
value
and
std
::
is_nothrow_move_constructible
<
pointer
>::
value
and
std
::
is_nothrow_move_assignable
<
pointer
>::
value
and
std
::
is_nothrow_move_assignable
<
pointer
>::
value
and
std
::
is_nothrow_move_constructible
<
internal_iterator
>::
value
and
std
::
is_nothrow_move_constructible
<
internal_iterator
>::
value
and
std
::
is_nothrow_move_assignable
<
internal_iterator
>::
value
std
::
is_nothrow_move_assignable
<
internal_iterator
>::
value
)
)
{
{
std
::
swap
(
m_object
,
other
.
m_object
);
base_iterator
::
operator
=
(
other
);
std
::
swap
(
m_it
,
other
.
m_it
);
return
*
this
;
return
*
this
;
}
}
private
:
/// return a reference to the value pointed to by the iterator
/// set the iterator to the first value
reference
operator
*
()
void
set_begin
()
{
{
switch
(
m_object
->
m_type
)
return
const_cast
<
reference
>
(
base_iterator
::
operator
*
());
{
}
case
(
basic_json
:
:
value_t
::
object
)
:
{
m_it
.
object_iterator
=
m_object
->
m_value
.
object
->
begin
();
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
/// dereference the iterator
{
pointer
operator
->
()
m_it
.
array_iterator
=
m_object
->
m_value
.
array
->
begin
();
{
break
;
return
const_cast
<
pointer
>
(
base_iterator
::
operator
->
())
;
}
}
case
(
basic_json
:
:
value_t
::
null
)
:
/// post-increment (it++)
{
iterator
operator
++
(
int
)
// set to end so begin()==end() is true: null is empty
{
m_it
.
primitive_iterator
.
set_end
();
iterator
result
=
*
this
;
break
;
base_iterator
::
operator
++
();
}
return
result
;
}
default
:
/// pre-increment (++it)
{
iterator
&
operator
++
()
m_it
.
primitive_iterator
.
set_begin
();
{
break
;
base_iterator
::
operator
++
();
}
return
*
this
;
}
}
}
///
set the iterator past the last value
///
post-decrement (it--)
void
set_end
(
)
iterator
operator
--
(
int
)
{
{
switch
(
m_object
->
m_type
)
iterator
result
=
*
this
;
{
base_iterator
::
operator
--
();
case
(
basic_json
:
:
value_t
::
object
)
:
return
result
;
{
}
m_it
.
object_iterator
=
m_object
->
m_value
.
object
->
end
();
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
/// pre-decrement (--it)
{
iterator
&
operator
--
()
m_it
.
array_iterator
=
m_object
->
m_value
.
array
->
end
();
{
break
;
base_iterator
::
operator
--
();
}
return
*
this
;
}
default
:
{
m_it
.
primitive_iterator
.
set_end
();
break
;
}
}
}
public
:
/// return a reference to the value pointed to by the iterator
reference
operator
*
()
const
{
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
return
m_it
.
object_iterator
->
second
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
return
*
m_it
.
array_iterator
;
}
case
(
basic_json
:
:
value_t
::
null
)
:
{
throw
std
::
out_of_range
(
"cannot get value"
);
}
default
:
{
if
(
m_it
.
primitive_iterator
.
is_begin
())
{
return
*
m_object
;
}
else
{
throw
std
::
out_of_range
(
"cannot get value"
);
}
}
}
}
/// dereference the iterator
pointer
operator
->
()
const
{
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
return
&
(
m_it
.
object_iterator
->
second
);
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
return
&*
m_it
.
array_iterator
;
}
default
:
{
if
(
m_it
.
primitive_iterator
.
is_begin
())
{
return
m_object
;
}
else
{
throw
std
::
out_of_range
(
"cannot get value"
);
}
}
}
}
/// post-increment (it++)
const_iterator
operator
++
(
int
)
{
auto
result
=
*
this
;
++
(
*
this
);
return
result
;
}
/// pre-increment (++it)
const_iterator
&
operator
++
()
{
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
++
m_it
.
object_iterator
;
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
++
m_it
.
array_iterator
;
break
;
}
default
:
{
++
m_it
.
primitive_iterator
;
break
;
}
}
return
*
this
;
}
/// post-decrement (it--)
const_iterator
operator
--
(
int
)
{
auto
result
=
*
this
;
--
(
*
this
);
return
result
;
}
/// pre-decrement (--it)
const_iterator
&
operator
--
()
{
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
--
m_it
.
object_iterator
;
break
;
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
--
m_it
.
array_iterator
;
break
;
}
default
:
{
--
m_it
.
primitive_iterator
;
break
;
}
}
return
*
this
;
}
/// comparison: equal
bool
operator
==
(
const
const_iterator
&
other
)
const
{
// if objects are not the same, the comparison is undefined
if
(
m_object
!=
other
.
m_object
)
{
throw
std
::
domain_error
(
"cannot compare iterators of different containers"
);
}
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
return
(
m_it
.
object_iterator
==
other
.
m_it
.
object_iterator
);
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
return
(
m_it
.
array_iterator
==
other
.
m_it
.
array_iterator
);
}
default
:
{
return
(
m_it
.
primitive_iterator
==
other
.
m_it
.
primitive_iterator
);
}
}
}
/// comparison: not equal
bool
operator
!=
(
const
const_iterator
&
other
)
const
{
return
not
operator
==
(
other
);
}
/// comparison: smaller
bool
operator
<
(
const
const_iterator
&
other
)
const
{
// if objects are not the same, the comparison is undefined
if
(
m_object
!=
other
.
m_object
)
{
throw
std
::
domain_error
(
"cannot compare iterators of different containers"
);
}
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
throw
std
::
domain_error
(
"cannot use operator< for object iterators"
);
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
return
(
m_it
.
array_iterator
<
other
.
m_it
.
array_iterator
);
}
default
:
{
return
(
m_it
.
primitive_iterator
<
other
.
m_it
.
primitive_iterator
);
}
}
}
/// comparison: less than or equal
bool
operator
<=
(
const
const_iterator
&
other
)
const
{
return
not
other
.
operator
<
(
*
this
);
}
/// comparison: greater than
bool
operator
>
(
const
const_iterator
&
other
)
const
{
return
not
operator
<=
(
other
);
}
/// comparison: greater than or equal
bool
operator
>=
(
const
const_iterator
&
other
)
const
{
return
not
operator
<
(
other
);
}
/// add to iterator
/// add to iterator
const_
iterator
&
operator
+=
(
difference_type
i
)
iterator
&
operator
+=
(
difference_type
i
)
{
{
switch
(
m_object
->
m_type
)
base_iterator
::
operator
+=
(
i
);
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
throw
std
::
domain_error
(
"cannot use operator+= for object iterators"
);
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
m_it
.
array_iterator
+=
i
;
break
;
}
default
:
{
m_it
.
primitive_iterator
+=
i
;
break
;
}
}
return
*
this
;
return
*
this
;
}
}
/// subtract from iterator
/// subtract from iterator
const_
iterator
&
operator
-=
(
difference_type
i
)
iterator
&
operator
-=
(
difference_type
i
)
{
{
return
operator
+=
(
-
i
);
base_iterator
::
operator
-=
(
i
);
return
*
this
;
}
}
/// add to iterator
/// add to iterator
const_
iterator
operator
+
(
difference_type
i
)
iterator
operator
+
(
difference_type
i
)
{
{
auto
result
=
*
this
;
auto
result
=
*
this
;
result
+=
i
;
result
+=
i
;
...
@@ -5781,163 +5458,82 @@ class basic_json
...
@@ -5781,163 +5458,82 @@ class basic_json
}
}
/// subtract from iterator
/// subtract from iterator
const_
iterator
operator
-
(
difference_type
i
)
iterator
operator
-
(
difference_type
i
)
{
{
auto
result
=
*
this
;
auto
result
=
*
this
;
result
-=
i
;
result
-=
i
;
return
result
;
return
result
;
}
}
/// return difference
difference_type
operator
-
(
const
iterator
&
other
)
const
difference_type
operator
-
(
const
const_iterator
&
other
)
const
{
{
switch
(
m_object
->
m_type
)
return
base_iterator
::
operator
-
(
other
);
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
throw
std
::
domain_error
(
"cannot use operator- for object iterators"
);
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
return
m_it
.
array_iterator
-
other
.
m_it
.
array_iterator
;
}
default
:
{
return
m_it
.
primitive_iterator
-
other
.
m_it
.
primitive_iterator
;
}
}
}
}
/// access to successor
/// access to successor
reference
operator
[](
difference_type
n
)
const
reference
operator
[](
difference_type
n
)
const
{
{
switch
(
m_object
->
m_type
)
return
const_cast
<
reference
>
(
base_iterator
::
operator
[](
n
));
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
throw
std
::
domain_error
(
"cannot use operator[] for object iterators"
);
}
case
(
basic_json
:
:
value_t
::
array
)
:
{
return
*
(
m_it
.
array_iterator
+
n
);
}
case
(
basic_json
:
:
value_t
::
null
)
:
{
throw
std
::
out_of_range
(
"cannot get value"
);
}
default
:
{
if
(
m_it
.
primitive_iterator
==
-
n
)
{
return
*
m_object
;
}
else
{
throw
std
::
out_of_range
(
"cannot get value"
);
}
}
}
}
/// return the key of an object iterator
typename
object_t
::
key_type
key
()
const
{
switch
(
m_object
->
m_type
)
{
case
(
basic_json
:
:
value_t
::
object
)
:
{
return
m_it
.
object_iterator
->
first
;
}
default
:
{
throw
std
::
domain_error
(
"cannot use key() for non-object iterators"
);
}
}
}
}
/// return the value of an iterator
/// return the value of an iterator
reference
value
()
const
reference
value
()
const
{
{
return
operator
*
(
);
return
const_cast
<
reference
>
(
base_iterator
::
value
()
);
}
}
private
:
/// associated JSON instance
pointer
m_object
=
nullptr
;
/// the actual iterator of the associated instance
internal_iterator
m_it
=
internal_iterator
();
};
};
/*!
/// a template for a reverse iterator class
@brief a reverse random access iterator for the basic_json class
template
<
typename
Base
>
class
json_reverse_iterator
:
public
std
::
reverse_iterator
<
Base
>
The reverse iterator is realized with the `std::reverse_iterator` adaptor.
This adaptor does not automatically inherit all functionality from the
base iterator class, so some functions need to be explicitly implemented
by either delegating them to the base class or by using the `base()`
function to access the underlying base iterator.
The following operators are implicitly inherited:
- `operator==`, `operator!=`, `operator<`, `operator<=`, `operator>`,
`operator>=`
- `operator-=`
- `operator->`, `operator*`
*/
class
reverse_iterator
:
public
std
::
reverse_iterator
<
typename
basic_json
::
iterator
>
{
{
public
:
public
:
/// shortcut to the reverse iterator adaptor
/// shortcut to the reverse iterator adaptor
using
base_iterator
=
std
::
reverse_iterator
<
typename
basic_json
::
iterator
>
;
using
base_iterator
=
std
::
reverse_iterator
<
Base
>
;
using
reference
=
typename
Base
::
reference
;
/// create reverse iterator from iterator
/// create reverse iterator from iterator
reverse_iterator
(
const
typename
base_iterator
::
iterator_type
&
it
)
json_
reverse_iterator
(
const
typename
base_iterator
::
iterator_type
&
it
)
:
base_iterator
(
it
)
{}
:
base_iterator
(
it
)
{}
/// create reverse iterator from base class
/// create reverse iterator from base class
reverse_iterator
(
const
base_iterator
&
it
)
:
base_iterator
(
it
)
{}
json_
reverse_iterator
(
const
base_iterator
&
it
)
:
base_iterator
(
it
)
{}
/// post-increment (it++)
/// post-increment (it++)
reverse_iterator
operator
++
(
int
)
json_
reverse_iterator
operator
++
(
int
)
{
{
return
base_iterator
::
operator
++
(
1
);
return
base_iterator
::
operator
++
(
1
);
}
}
/// pre-increment (++it)
/// pre-increment (++it)
reverse_iterator
&
operator
++
()
json_
reverse_iterator
&
operator
++
()
{
{
base_iterator
::
operator
++
();
base_iterator
::
operator
++
();
return
*
this
;
return
*
this
;
}
}
/// post-decrement (it--)
/// post-decrement (it--)
reverse_iterator
operator
--
(
int
)
json_
reverse_iterator
operator
--
(
int
)
{
{
return
base_iterator
::
operator
--
(
1
);
return
base_iterator
::
operator
--
(
1
);
}
}
/// pre-decrement (--it)
/// pre-decrement (--it)
reverse_iterator
&
operator
--
()
json_
reverse_iterator
&
operator
--
()
{
{
base_iterator
::
operator
--
();
base_iterator
::
operator
--
();
return
*
this
;
return
*
this
;
}
}
/// add to iterator
/// add to iterator
reverse_iterator
&
operator
+=
(
difference_type
i
)
json_
reverse_iterator
&
operator
+=
(
difference_type
i
)
{
{
base_iterator
::
operator
+=
(
i
);
base_iterator
::
operator
+=
(
i
);
return
*
this
;
return
*
this
;
}
}
/// add to iterator
/// add to iterator
reverse_iterator
operator
+
(
difference_type
i
)
const
json_
reverse_iterator
operator
+
(
difference_type
i
)
const
{
{
auto
result
=
*
this
;
auto
result
=
*
this
;
result
+=
i
;
result
+=
i
;
...
@@ -5945,7 +5541,7 @@ class basic_json
...
@@ -5945,7 +5541,7 @@ class basic_json
}
}
/// subtract from iterator
/// subtract from iterator
reverse_iterator
operator
-
(
difference_type
i
)
const
json_
reverse_iterator
operator
-
(
difference_type
i
)
const
{
{
auto
result
=
*
this
;
auto
result
=
*
this
;
result
-=
i
;
result
-=
i
;
...
@@ -5953,7 +5549,7 @@ class basic_json
...
@@ -5953,7 +5549,7 @@ class basic_json
}
}
/// return difference
/// return difference
difference_type
operator
-
(
const
reverse_iterator
&
other
)
const
difference_type
operator
-
(
const
json_
reverse_iterator
&
other
)
const
{
{
return
this
->
base
()
-
other
.
base
();
return
this
->
base
()
-
other
.
base
();
}
}
...
@@ -5979,97 +5575,6 @@ class basic_json
...
@@ -5979,97 +5575,6 @@ class basic_json
}
}
};
};
/// a const reverse random access iterator for the basic_json class
class
const_reverse_iterator
:
public
std
::
reverse_iterator
<
typename
basic_json
::
const_iterator
>
{
public
:
/// shortcut to the reverse iterator adaptor
using
base_iterator
=
std
::
reverse_iterator
<
typename
basic_json
::
const_iterator
>
;
/// create reverse iterator from iterator
const_reverse_iterator
(
const
typename
base_iterator
::
iterator_type
&
it
)
:
base_iterator
(
it
)
{}
/// create reverse iterator from base class
const_reverse_iterator
(
const
base_iterator
&
it
)
:
base_iterator
(
it
)
{}
/// post-increment (it++)
const_reverse_iterator
operator
++
(
int
)
{
return
base_iterator
::
operator
++
(
1
);
}
/// pre-increment (++it)
const_reverse_iterator
&
operator
++
()
{
base_iterator
::
operator
++
();
return
*
this
;
}
/// post-decrement (it--)
const_reverse_iterator
operator
--
(
int
)
{
return
base_iterator
::
operator
--
(
1
);
}
/// pre-decrement (--it)
const_reverse_iterator
&
operator
--
()
{
base_iterator
::
operator
--
();
return
*
this
;
}
/// add to iterator
const_reverse_iterator
&
operator
+=
(
difference_type
i
)
{
base_iterator
::
operator
+=
(
i
);
return
*
this
;
}
/// add to iterator
const_reverse_iterator
operator
+
(
difference_type
i
)
const
{
auto
result
=
*
this
;
result
+=
i
;
return
result
;
}
/// subtract from iterator
const_reverse_iterator
operator
-
(
difference_type
i
)
const
{
auto
result
=
*
this
;
result
-=
i
;
return
result
;
}
/// return difference
difference_type
operator
-
(
const
const_reverse_iterator
&
other
)
const
{
return
this
->
base
()
-
other
.
base
();
}
/// access to successor
const_reference
operator
[](
difference_type
n
)
const
{
return
*
(
this
->
operator
+
(
n
));
}
/// return the key of an object iterator
typename
object_t
::
key_type
key
()
const
{
auto
it
=
--
this
->
base
();
return
it
.
key
();
}
/// return the value of an iterator
const_reference
value
()
const
{
auto
it
=
--
this
->
base
();
return
it
.
operator
*
();
}
};
private
:
private
:
//////////////////////
//////////////////////
// lexer and parser //
// lexer and parser //
...
...
src/json.hpp.re2c
View file @
5c813b61
...
@@ -172,14 +172,17 @@ class basic_json
...
@@ -172,14 +172,17 @@ class basic_json
/// the type of an element const pointer
/// the type of an element const pointer
using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
using const_pointer = typename std::allocator_traits<allocator_type>::const_pointer;
// forward declaration
template<typename Base> class json_reverse_iterator;
/// an iterator for a basic_json container
/// an iterator for a basic_json container
class iterator;
class iterator;
/// a const iterator for a basic_json container
/// a const iterator for a basic_json container
class const_iterator;
class const_iterator;
/// a reverse iterator for a basic_json container
/// a reverse iterator for a basic_json container
class reverse_iterator
;
using reverse_iterator = json_reverse_iterator<typename basic_json::iterator>
;
/// a const reverse iterator for a basic_json container
/// a const reverse iterator for a basic_json container
class const_reverse_iterator
;
using const_reverse_iterator = json_reverse_iterator<typename basic_json::const_iterator>
;
/// @}
/// @}
...
@@ -4863,8 +4866,8 @@ class basic_json
...
@@ -4863,8 +4866,8 @@ class basic_json
};
};
public:
public:
/// a random access iterator for the basic_json class
/// a
const
random access iterator for the basic_json class
class
iterator : public std::iterator<std::random_access_iterator_tag,
basic_json>
class
const_iterator : public std::iterator<std::random_access_iterator_tag, const
basic_json>
{
{
// allow basic_json class to access m_it
// allow basic_json class to access m_it
friend class basic_json;
friend class basic_json;
...
@@ -4875,17 +4878,17 @@ class basic_json
...
@@ -4875,17 +4878,17 @@ class basic_json
/// a type to represent differences between iterators
/// a type to represent differences between iterators
using difference_type = typename basic_json::difference_type;
using difference_type = typename basic_json::difference_type;
/// defines a pointer to the type iterated over (value_type)
/// defines a pointer to the type iterated over (value_type)
using pointer = typename basic_json::pointer;
using pointer = typename basic_json::
const_
pointer;
/// defines a reference to the type iterated over (value_type)
/// defines a reference to the type iterated over (value_type)
using reference = typename basic_json::reference;
using reference = typename basic_json::
const_
reference;
/// the category of the iterator
/// the category of the iterator
using iterator_category = std::bidirectional_iterator_tag;
using iterator_category = std::bidirectional_iterator_tag;
/// default constructor
/// default constructor
iterator() = default;
const_
iterator() = default;
/// constructor for a given JSON instance
/// constructor for a given JSON instance
iterator(pointer object) : m_object(object)
const_
iterator(pointer object) : m_object(object)
{
{
switch (m_object->m_type)
switch (m_object->m_type)
{
{
...
@@ -4907,13 +4910,38 @@ class basic_json
...
@@ -4907,13 +4910,38 @@ class basic_json
}
}
}
}
/// copy constructor given a nonconst iterator
const_iterator(const iterator& other) : m_object(other.m_object)
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator = other.m_it.object_iterator;
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator = other.m_it.array_iterator;
break;
}
default:
{
m_it.primitive_iterator = other.m_it.primitive_iterator;
break;
}
}
}
/// copy constructor
/// copy constructor
iterator(const
iterator& other) noexcept
const_iterator(const const_
iterator& other) noexcept
: m_object(other.m_object), m_it(other.m_it)
: m_object(other.m_object), m_it(other.m_it)
{}
{}
/// copy assignment
/// copy assignment
iterator& operator=(iterator other) noexcept
(
const_iterator& operator=(const_iterator other) noexcept
(
std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and
...
@@ -4985,7 +5013,7 @@ class basic_json
...
@@ -4985,7 +5013,7 @@ class basic_json
public:
public:
/// return a reference to the value pointed to by the iterator
/// return a reference to the value pointed to by the iterator
reference operator*()
reference operator*()
const
{
{
switch (m_object->m_type)
switch (m_object->m_type)
{
{
...
@@ -5019,7 +5047,7 @@ class basic_json
...
@@ -5019,7 +5047,7 @@ class basic_json
}
}
/// dereference the iterator
/// dereference the iterator
pointer operator->()
pointer operator->()
const
{
{
switch (m_object->m_type)
switch (m_object->m_type)
{
{
...
@@ -5033,11 +5061,6 @@ class basic_json
...
@@ -5033,11 +5061,6 @@ class basic_json
return &*m_it.array_iterator;
return &*m_it.array_iterator;
}
}
case (basic_json::value_t::null):
{
throw std::out_of_range("cannot get value");
}
default:
default:
{
{
if (m_it.primitive_iterator.is_begin())
if (m_it.primitive_iterator.is_begin())
...
@@ -5053,36 +5076,16 @@ class basic_json
...
@@ -5053,36 +5076,16 @@ class basic_json
}
}
/// post-increment (it++)
/// post-increment (it++)
iterator operator++(int)
const_
iterator operator++(int)
{
{
auto result = *this;
auto result = *this;
++(*this);
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator++;
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator++;
break;
}
default:
{
m_it.primitive_iterator++;
break;
}
}
return result;
return result;
}
}
/// pre-increment (++it)
/// pre-increment (++it)
iterator& operator++()
const_
iterator& operator++()
{
{
switch (m_object->m_type)
switch (m_object->m_type)
{
{
...
@@ -5109,36 +5112,16 @@ class basic_json
...
@@ -5109,36 +5112,16 @@ class basic_json
}
}
/// post-decrement (it--)
/// post-decrement (it--)
iterator operator--(int)
const_
iterator operator--(int)
{
{
auto result = *this;
auto result = *this;
--(*this);
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator--;
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator--;
break;
}
default:
{
m_it.primitive_iterator--;
break;
}
}
return result;
return result;
}
}
/// pre-decrement (--it)
/// pre-decrement (--it)
iterator& operator--()
const_
iterator& operator--()
{
{
switch (m_object->m_type)
switch (m_object->m_type)
{
{
...
@@ -5165,7 +5148,7 @@ class basic_json
...
@@ -5165,7 +5148,7 @@ class basic_json
}
}
/// comparison: equal
/// comparison: equal
bool operator==(const iterator& other) const
bool operator==(const
const_
iterator& other) const
{
{
// if objects are not the same, the comparison is undefined
// if objects are not the same, the comparison is undefined
if (m_object != other.m_object)
if (m_object != other.m_object)
...
@@ -5193,13 +5176,13 @@ class basic_json
...
@@ -5193,13 +5176,13 @@ class basic_json
}
}
/// comparison: not equal
/// comparison: not equal
bool operator!=(const iterator& other) const
bool operator!=(const
const_
iterator& other) const
{
{
return not operator==(other);
return not operator==(other);
}
}
/// comparison: smaller
/// comparison: smaller
bool operator<(const iterator& other) const
bool operator<(const
const_
iterator& other) const
{
{
// if objects are not the same, the comparison is undefined
// if objects are not the same, the comparison is undefined
if (m_object != other.m_object)
if (m_object != other.m_object)
...
@@ -5227,25 +5210,25 @@ class basic_json
...
@@ -5227,25 +5210,25 @@ class basic_json
}
}
/// comparison: less than or equal
/// comparison: less than or equal
bool operator<=(const iterator& other) const
bool operator<=(const
const_
iterator& other) const
{
{
return not other.operator < (*this);
return not other.operator < (*this);
}
}
/// comparison: greater than
/// comparison: greater than
bool operator>(const iterator& other) const
bool operator>(const
const_
iterator& other) const
{
{
return not operator<=(other);
return not operator<=(other);
}
}
/// comparison: greater than or equal
/// comparison: greater than or equal
bool operator>=(const iterator& other) const
bool operator>=(const
const_
iterator& other) const
{
{
return not operator<(other);
return not operator<(other);
}
}
/// add to iterator
/// add to iterator
iterator& operator+=(difference_type i)
const_
iterator& operator+=(difference_type i)
{
{
switch (m_object->m_type)
switch (m_object->m_type)
{
{
...
@@ -5271,13 +5254,13 @@ class basic_json
...
@@ -5271,13 +5254,13 @@ class basic_json
}
}
/// subtract from iterator
/// subtract from iterator
iterator& operator-=(difference_type i)
const_
iterator& operator-=(difference_type i)
{
{
return operator+=(-i);
return operator+=(-i);
}
}
/// add to iterator
/// add to iterator
iterator operator+(difference_type i)
const_
iterator operator+(difference_type i)
{
{
auto result = *this;
auto result = *this;
result += i;
result += i;
...
@@ -5285,7 +5268,7 @@ class basic_json
...
@@ -5285,7 +5268,7 @@ class basic_json
}
}
/// subtract from iterator
/// subtract from iterator
iterator operator-(difference_type i)
const_
iterator operator-(difference_type i)
{
{
auto result = *this;
auto result = *this;
result -= i;
result -= i;
...
@@ -5293,14 +5276,13 @@ class basic_json
...
@@ -5293,14 +5276,13 @@ class basic_json
}
}
/// return difference
/// return difference
difference_type operator-(const iterator& other) const
difference_type operator-(const
const_
iterator& other) const
{
{
switch (m_object->m_type)
switch (m_object->m_type)
{
{
case (basic_json::value_t::object):
case (basic_json::value_t::object):
{
{
throw std::domain_error("cannot use operator- for object iterators");
throw std::domain_error("cannot use operator- for object iterators");
return 0;
}
}
case (basic_json::value_t::array):
case (basic_json::value_t::array):
...
@@ -5316,7 +5298,7 @@ class basic_json
...
@@ -5316,7 +5298,7 @@ class basic_json
}
}
/// access to successor
/// access to successor
reference operator[](difference_type n)
reference operator[](difference_type n)
const
{
{
switch (m_object->m_type)
switch (m_object->m_type)
{
{
...
@@ -5366,8 +5348,8 @@ class basic_json
...
@@ -5366,8 +5348,8 @@ class basic_json
}
}
}
}
/// return the
key
of an iterator
/// return the
value
of an iterator
reference value()
reference value()
const
{
{
return operator*();
return operator*();
}
}
...
@@ -5379,401 +5361,96 @@ class basic_json
...
@@ -5379,401 +5361,96 @@ class basic_json
internal_iterator m_it = internal_iterator();
internal_iterator m_it = internal_iterator();
};
};
/// a
const
random access iterator for the basic_json class
/// a random access iterator for the basic_json class
class
const_iterator : public std::iterator<std::random_access_iterator_tag, const basic_json>
class
iterator : public const_iterator
{
{
// allow basic_json class to access m_it
friend class basic_json;
public:
public:
/// the type of the values when the iterator is dereferenced
using base_iterator = const_iterator;
using value_type = typename basic_json::value_type;
using pointer = typename basic_json::pointer;
/// a type to represent differences between iterators
using reference = typename basic_json::reference;
using difference_type = typename basic_json::difference_type;
/// defines a pointer to the type iterated over (value_type)
using pointer = typename basic_json::const_pointer;
/// defines a reference to the type iterated over (value_type)
using reference = typename basic_json::const_reference;
/// the category of the iterator
using iterator_category = std::bidirectional_iterator_tag;
/// default constructor
/// default constructor
const_
iterator() = default;
iterator() = default;
/// constructor for a given JSON instance
/// constructor for a given JSON instance
const_iterator(pointer object) : m_object(object)
iterator(pointer object) noexcept : base_iterator(object)
{
{}
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator = typename object_t::iterator();
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator = typename array_t::iterator();
break;
}
default:
{
m_it.primitive_iterator = primitive_iterator_t();
break;
}
}
}
/// copy constructor given a nonconst iterator
const_iterator(const iterator& other) : m_object(other.m_object)
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
m_it.object_iterator = other.m_it.object_iterator;
break;
}
case (basic_json::value_t::array):
{
m_it.array_iterator = other.m_it.array_iterator;
break;
}
default:
{
m_it.primitive_iterator = other.m_it.primitive_iterator;
break;
}
}
}
/// copy constructor
/// copy constructor
const_iterator(const const_
iterator& other) noexcept
iterator(const
iterator& other) noexcept
:
m_object(other.m_object), m_it(other.m_it
)
:
base_iterator(other
)
{}
{}
/// copy assignment
/// copy assignment
const_iterator& operator=(const_
iterator other) noexcept(
iterator& operator=(
iterator other) noexcept(
std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_constructible<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_assignable<pointer>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and
std::is_nothrow_move_constructible<internal_iterator>::value and
std::is_nothrow_move_assignable<internal_iterator>::value
std::is_nothrow_move_assignable<internal_iterator>::value
)
)
{
{
std::swap(m_object, other.m_object);
base_iterator::operator=(other);
std::swap(m_it, other.m_it);
return *this;
return *this;
}
}
private:
/// return a reference to the value pointed to by the iterator
/// set the iterator to the first value
reference operator*()
void set_begin()
{
{
switch (m_object->m_type)
return const_cast<reference>(base_iterator::operator*());
{
}
case (basic_json::value_t::object):
{
m_it.object_iterator = m_object->m_value.object->begin();
break;
}
case (basic_json::value_t::array):
/// dereference the iterator
{
pointer operator->()
m_it.array_iterator = m_object->m_value.array->begin();
{
break
;
return const_cast<pointer>(base_iterator::operator->())
;
}
}
case (basic_json::value_t::null):
/// post-increment (it++)
{
iterator operator++(int)
// set to end so begin()==end() is true: null is empty
{
m_it.primitive_iterator.set_end();
iterator result = *this;
break;
base_iterator::operator++();
}
return result;
}
default:
/// pre-increment (++it)
{
iterator& operator++()
m_it.primitive_iterator.set_begin();
{
break;
base_iterator::operator++();
}
return *this;
}
}
}
///
set the iterator past the last value
///
post-decrement (it--)
void set_end(
)
iterator operator--(int
)
{
{
switch (m_object->m_type)
iterator result = *this;
{
base_iterator::operator--();
case (basic_json::value_t::object):
return result;
{
}
m_it.object_iterator = m_object->m_value.object->end();
break;
}
case (basic_json::value_t::array):
/// pre-decrement (--it)
{
iterator& operator--()
m_it.array_iterator = m_object->m_value.array->end();
{
break;
base_iterator::operator--();
}
return *this;
}
default:
{
m_it.primitive_iterator.set_end();
break;
}
}
}
public:
/// return a reference to the value pointed to by the iterator
reference operator*() const
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
return m_it.object_iterator->second;
}
case (basic_json::value_t::array):
{
return *m_it.array_iterator;
}
case (basic_json::value_t::null):
{
throw std::out_of_range("cannot get value");
}
default:
{
if (m_it.primitive_iterator.is_begin())
{
return *m_object;
}
else
{
throw std::out_of_range("cannot get value");
}
}
}
}
/// dereference the iterator
pointer operator->() const
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
return &(m_it.object_iterator->second);
}
case (basic_json::value_t::array):
{
return &*m_it.array_iterator;
}
default:
{
if (m_it.primitive_iterator.is_begin())
{
return m_object;
}
else
{
throw std::out_of_range("cannot get value");
}
}
}
}
/// post-increment (it++)
const_iterator operator++(int)
{
auto result = *this;
++(*this);
return result;
}
/// pre-increment (++it)
const_iterator& operator++()
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
++m_it.object_iterator;
break;
}
case (basic_json::value_t::array):
{
++m_it.array_iterator;
break;
}
default:
{
++m_it.primitive_iterator;
break;
}
}
return *this;
}
/// post-decrement (it--)
const_iterator operator--(int)
{
auto result = *this;
--(*this);
return result;
}
/// pre-decrement (--it)
const_iterator& operator--()
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
--m_it.object_iterator;
break;
}
case (basic_json::value_t::array):
{
--m_it.array_iterator;
break;
}
default:
{
--m_it.primitive_iterator;
break;
}
}
return *this;
}
/// comparison: equal
bool operator==(const const_iterator& other) const
{
// if objects are not the same, the comparison is undefined
if (m_object != other.m_object)
{
throw std::domain_error("cannot compare iterators of different containers");
}
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
return (m_it.object_iterator == other.m_it.object_iterator);
}
case (basic_json::value_t::array):
{
return (m_it.array_iterator == other.m_it.array_iterator);
}
default:
{
return (m_it.primitive_iterator == other.m_it.primitive_iterator);
}
}
}
/// comparison: not equal
bool operator!=(const const_iterator& other) const
{
return not operator==(other);
}
/// comparison: smaller
bool operator<(const const_iterator& other) const
{
// if objects are not the same, the comparison is undefined
if (m_object != other.m_object)
{
throw std::domain_error("cannot compare iterators of different containers");
}
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
throw std::domain_error("cannot use operator< for object iterators");
}
case (basic_json::value_t::array):
{
return (m_it.array_iterator < other.m_it.array_iterator);
}
default:
{
return (m_it.primitive_iterator < other.m_it.primitive_iterator);
}
}
}
/// comparison: less than or equal
bool operator<=(const const_iterator& other) const
{
return not other.operator < (*this);
}
/// comparison: greater than
bool operator>(const const_iterator& other) const
{
return not operator<=(other);
}
/// comparison: greater than or equal
bool operator>=(const const_iterator& other) const
{
return not operator<(other);
}
/// add to iterator
/// add to iterator
const_
iterator& operator+=(difference_type i)
iterator& operator+=(difference_type i)
{
{
switch (m_object->m_type)
base_iterator::operator+=(i);
{
case (basic_json::value_t::object):
{
throw std::domain_error("cannot use operator+= for object iterators");
}
case (basic_json::value_t::array):
{
m_it.array_iterator += i;
break;
}
default:
{
m_it.primitive_iterator += i;
break;
}
}
return *this;
return *this;
}
}
/// subtract from iterator
/// subtract from iterator
const_
iterator& operator-=(difference_type i)
iterator& operator-=(difference_type i)
{
{
return operator+=(-i);
base_iterator::operator-=(i);
return *this;
}
}
/// add to iterator
/// add to iterator
const_
iterator operator+(difference_type i)
iterator operator+(difference_type i)
{
{
auto result = *this;
auto result = *this;
result += i;
result += i;
...
@@ -5781,163 +5458,82 @@ class basic_json
...
@@ -5781,163 +5458,82 @@ class basic_json
}
}
/// subtract from iterator
/// subtract from iterator
const_
iterator operator-(difference_type i)
iterator operator-(difference_type i)
{
{
auto result = *this;
auto result = *this;
result -= i;
result -= i;
return result;
return result;
}
}
/// return difference
difference_type operator-(const iterator& other) const
difference_type operator-(const const_iterator& other) const
{
{
switch (m_object->m_type)
return base_iterator::operator-(other);
{
case (basic_json::value_t::object):
{
throw std::domain_error("cannot use operator- for object iterators");
}
case (basic_json::value_t::array):
{
return m_it.array_iterator - other.m_it.array_iterator;
}
default:
{
return m_it.primitive_iterator - other.m_it.primitive_iterator;
}
}
}
}
/// access to successor
/// access to successor
reference operator[](difference_type n) const
reference operator[](difference_type n) const
{
{
switch (m_object->m_type)
return const_cast<reference>(base_iterator::operator[](n));
{
case (basic_json::value_t::object):
{
throw std::domain_error("cannot use operator[] for object iterators");
}
case (basic_json::value_t::array):
{
return *(m_it.array_iterator + n);
}
case (basic_json::value_t::null):
{
throw std::out_of_range("cannot get value");
}
default:
{
if (m_it.primitive_iterator == -n)
{
return *m_object;
}
else
{
throw std::out_of_range("cannot get value");
}
}
}
}
/// return the key of an object iterator
typename object_t::key_type key() const
{
switch (m_object->m_type)
{
case (basic_json::value_t::object):
{
return m_it.object_iterator->first;
}
default:
{
throw std::domain_error("cannot use key() for non-object iterators");
}
}
}
}
/// return the value of an iterator
/// return the value of an iterator
reference value() const
reference value() const
{
{
return
operator*(
);
return
const_cast<reference>(base_iterator::value()
);
}
}
private:
/// associated JSON instance
pointer m_object = nullptr;
/// the actual iterator of the associated instance
internal_iterator m_it = internal_iterator();
};
};
/*!
/// a template for a reverse iterator class
@brief a reverse random access iterator for the basic_json class
template<typename Base>
class json_reverse_iterator : public std::reverse_iterator<Base>
The reverse iterator is realized with the `std::reverse_iterator` adaptor.
This adaptor does not automatically inherit all functionality from the
base iterator class, so some functions need to be explicitly implemented
by either delegating them to the base class or by using the `base()`
function to access the underlying base iterator.
The following operators are implicitly inherited:
- `operator==`, `operator!=`, `operator<`, `operator<=`, `operator>`,
`operator>=`
- `operator-=`
- `operator->`, `operator*`
*/
class reverse_iterator : public std::reverse_iterator<typename basic_json::iterator>
{
{
public:
public:
/// shortcut to the reverse iterator adaptor
/// shortcut to the reverse iterator adaptor
using base_iterator = std::reverse_iterator<typename basic_json::iterator>;
using base_iterator = std::reverse_iterator<Base>;
using reference = typename Base::reference;
/// create reverse iterator from iterator
/// create reverse iterator from iterator
reverse_iterator(const typename base_iterator::iterator_type& it)
json_
reverse_iterator(const typename base_iterator::iterator_type& it)
: base_iterator(it) {}
: base_iterator(it) {}
/// create reverse iterator from base class
/// create reverse iterator from base class
reverse_iterator(const base_iterator& it) : base_iterator(it) {}
json_
reverse_iterator(const base_iterator& it) : base_iterator(it) {}
/// post-increment (it++)
/// post-increment (it++)
reverse_iterator operator++(int)
json_
reverse_iterator operator++(int)
{
{
return base_iterator::operator++(1);
return base_iterator::operator++(1);
}
}
/// pre-increment (++it)
/// pre-increment (++it)
reverse_iterator& operator++()
json_
reverse_iterator& operator++()
{
{
base_iterator::operator++();
base_iterator::operator++();
return *this;
return *this;
}
}
/// post-decrement (it--)
/// post-decrement (it--)
reverse_iterator operator--(int)
json_
reverse_iterator operator--(int)
{
{
return base_iterator::operator--(1);
return base_iterator::operator--(1);
}
}
/// pre-decrement (--it)
/// pre-decrement (--it)
reverse_iterator& operator--()
json_
reverse_iterator& operator--()
{
{
base_iterator::operator--();
base_iterator::operator--();
return *this;
return *this;
}
}
/// add to iterator
/// add to iterator
reverse_iterator& operator+=(difference_type i)
json_
reverse_iterator& operator+=(difference_type i)
{
{
base_iterator::operator+=(i);
base_iterator::operator+=(i);
return *this;
return *this;
}
}
/// add to iterator
/// add to iterator
reverse_iterator operator+(difference_type i) const
json_
reverse_iterator operator+(difference_type i) const
{
{
auto result = *this;
auto result = *this;
result += i;
result += i;
...
@@ -5945,7 +5541,7 @@ class basic_json
...
@@ -5945,7 +5541,7 @@ class basic_json
}
}
/// subtract from iterator
/// subtract from iterator
reverse_iterator operator-(difference_type i) const
json_
reverse_iterator operator-(difference_type i) const
{
{
auto result = *this;
auto result = *this;
result -= i;
result -= i;
...
@@ -5953,7 +5549,7 @@ class basic_json
...
@@ -5953,7 +5549,7 @@ class basic_json
}
}
/// return difference
/// return difference
difference_type operator-(const reverse_iterator& other) const
difference_type operator-(const
json_
reverse_iterator& other) const
{
{
return this->base() - other.base();
return this->base() - other.base();
}
}
...
@@ -5979,97 +5575,6 @@ class basic_json
...
@@ -5979,97 +5575,6 @@ class basic_json
}
}
};
};
/// a const reverse random access iterator for the basic_json class
class const_reverse_iterator : public std::reverse_iterator<typename basic_json::const_iterator>
{
public:
/// shortcut to the reverse iterator adaptor
using base_iterator = std::reverse_iterator<typename basic_json::const_iterator>;
/// create reverse iterator from iterator
const_reverse_iterator(const typename base_iterator::iterator_type& it)
: base_iterator(it) {}
/// create reverse iterator from base class
const_reverse_iterator(const base_iterator& it) : base_iterator(it) {}
/// post-increment (it++)
const_reverse_iterator operator++(int)
{
return base_iterator::operator++(1);
}
/// pre-increment (++it)
const_reverse_iterator& operator++()
{
base_iterator::operator++();
return *this;
}
/// post-decrement (it--)
const_reverse_iterator operator--(int)
{
return base_iterator::operator--(1);
}
/// pre-decrement (--it)
const_reverse_iterator& operator--()
{
base_iterator::operator--();
return *this;
}
/// add to iterator
const_reverse_iterator& operator+=(difference_type i)
{
base_iterator::operator+=(i);
return *this;
}
/// add to iterator
const_reverse_iterator operator+(difference_type i) const
{
auto result = *this;
result += i;
return result;
}
/// subtract from iterator
const_reverse_iterator operator-(difference_type i) const
{
auto result = *this;
result -= i;
return result;
}
/// return difference
difference_type operator-(const const_reverse_iterator& other) const
{
return this->base() - other.base();
}
/// access to successor
const_reference operator[](difference_type n) const
{
return *(this->operator+(n));
}
/// return the key of an object iterator
typename object_t::key_type key() const
{
auto it = --this->base();
return it.key();
}
/// return the value of an iterator
const_reference value() const
{
auto it = --this->base();
return it.operator * ();
}
};
private:
private:
//////////////////////
//////////////////////
// lexer and parser //
// lexer and parser //
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment