Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
A
Actor Framework
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
cpp-libs
Actor Framework
Commits
50984474
Commit
50984474
authored
Aug 26, 2022
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add new API for interacting with JSON values
parent
7168be7a
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1839 additions
and
53 deletions
+1839
-53
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+5
-0
libcaf_core/caf/detail/json.hpp
libcaf_core/caf/detail/json.hpp
+596
-10
libcaf_core/caf/detail/monotonic_buffer_resource.hpp
libcaf_core/caf/detail/monotonic_buffer_resource.hpp
+5
-5
libcaf_core/caf/fwd.hpp
libcaf_core/caf/fwd.hpp
+5
-0
libcaf_core/caf/json.hpp
libcaf_core/caf/json.hpp
+11
-0
libcaf_core/caf/json_array.hpp
libcaf_core/caf/json_array.hpp
+162
-0
libcaf_core/caf/json_object.hpp
libcaf_core/caf/json_object.hpp
+168
-0
libcaf_core/caf/json_value.hpp
libcaf_core/caf/json_value.hpp
+166
-0
libcaf_core/caf/parser_state.hpp
libcaf_core/caf/parser_state.hpp
+5
-0
libcaf_core/caf/type_id.hpp
libcaf_core/caf/type_id.hpp
+4
-1
libcaf_core/src/detail/json.cpp
libcaf_core/src/detail/json.cpp
+208
-36
libcaf_core/src/init_global_meta_objects.cpp
libcaf_core/src/init_global_meta_objects.cpp
+3
-0
libcaf_core/src/json_object.cpp
libcaf_core/src/json_object.cpp
+20
-0
libcaf_core/src/json_reader.cpp
libcaf_core/src/json_reader.cpp
+1
-1
libcaf_core/src/json_value.cpp
libcaf_core/src/json_value.cpp
+124
-0
libcaf_core/test/core-test.hpp
libcaf_core/test/core-test.hpp
+29
-0
libcaf_core/test/detail/json.cpp
libcaf_core/test/detail/json.cpp
+6
-0
libcaf_core/test/json_array.cpp
libcaf_core/test/json_array.cpp
+51
-0
libcaf_core/test/json_object.cpp
libcaf_core/test/json_object.cpp
+58
-0
libcaf_core/test/json_value.cpp
libcaf_core/test/json_value.cpp
+212
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
50984474
...
@@ -161,7 +161,9 @@ caf_add_component(
...
@@ -161,7 +161,9 @@ caf_add_component(
src/ipv6_address.cpp
src/ipv6_address.cpp
src/ipv6_endpoint.cpp
src/ipv6_endpoint.cpp
src/ipv6_subnet.cpp
src/ipv6_subnet.cpp
src/json_object.cpp
src/json_reader.cpp
src/json_reader.cpp
src/json_value.cpp
src/json_writer.cpp
src/json_writer.cpp
src/load_inspector.cpp
src/load_inspector.cpp
src/local_actor.cpp
src/local_actor.cpp
...
@@ -313,7 +315,10 @@ caf_add_component(
...
@@ -313,7 +315,10 @@ caf_add_component(
ipv6_address
ipv6_address
ipv6_endpoint
ipv6_endpoint
ipv6_subnet
ipv6_subnet
json_array
json_object
json_reader
json_reader
json_value
json_writer
json_writer
load_inspector
load_inspector
logger
logger
...
...
libcaf_core/caf/detail/json.hpp
View file @
50984474
This diff is collapsed.
Click to expand it.
libcaf_core/caf/detail/monotonic_buffer_resource.hpp
View file @
50984474
...
@@ -55,20 +55,20 @@ public:
...
@@ -55,20 +55,20 @@ public:
using
other
=
allocator
<
U
>
;
using
other
=
allocator
<
U
>
;
};
};
explicit
allocator
(
monotonic_buffer_resource
*
mbr
)
:
mbr_
(
mbr
)
{
constexpr
explicit
allocator
(
monotonic_buffer_resource
*
mbr
)
:
mbr_
(
mbr
)
{
// nop
// nop
}
}
allocator
()
:
mbr_
(
nullptr
)
{
constexpr
allocator
()
:
mbr_
(
nullptr
)
{
// nop
// nop
}
}
allocator
(
const
allocator
&
)
=
default
;
constexpr
allocator
(
const
allocator
&
)
=
default
;
allocator
&
operator
=
(
const
allocator
&
)
=
default
;
constexpr
allocator
&
operator
=
(
const
allocator
&
)
=
default
;
template
<
class
U
>
template
<
class
U
>
allocator
(
const
allocator
<
U
>&
other
)
:
mbr_
(
other
.
resource
())
{
constexpr
allocator
(
const
allocator
<
U
>&
other
)
:
mbr_
(
other
.
resource
())
{
// nop
// nop
}
}
...
...
libcaf_core/caf/fwd.hpp
View file @
50984474
...
@@ -110,6 +110,11 @@ class ipv4_subnet;
...
@@ -110,6 +110,11 @@ class ipv4_subnet;
class
ipv6_address
;
class
ipv6_address
;
class
ipv6_endpoint
;
class
ipv6_endpoint
;
class
ipv6_subnet
;
class
ipv6_subnet
;
class
json_array
;
class
json_object
;
class
json_reader
;
class
json_value
;
class
json_writer
;
class
local_actor
;
class
local_actor
;
class
mailbox_element
;
class
mailbox_element
;
class
message
;
class
message
;
...
...
libcaf_core/caf/json.hpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#pragma once
#include "caf/json_array.hpp"
#include "caf/json_object.hpp"
#include "caf/json_reader.hpp"
#include "caf/json_value.hpp"
#include "caf/json_writer.hpp"
libcaf_core/caf/json_array.hpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#pragma once
#include "caf/detail/core_export.hpp"
#include "caf/detail/json.hpp"
#include "caf/fwd.hpp"
#include "caf/json_value.hpp"
#include <iterator>
#include <memory>
namespace
caf
{
/// Represents a JSON array.
class
CAF_CORE_EXPORT
json_array
{
public:
// -- friends ----------------------------------------------------------------
friend
class
json_value
;
// -- member types -----------------------------------------------------------
class
const_iterator
{
public:
using
difference_type
=
ptrdiff_t
;
using
value_type
=
json_value
;
using
pointer
=
value_type
*
;
using
reference
=
value_type
&
;
using
iterator_category
=
std
::
forward_iterator_tag
;
const_iterator
(
detail
::
json
::
value
::
array
::
const_iterator
iter
,
detail
::
json
::
storage
*
storage
)
:
iter_
(
iter
),
storage_
(
storage
)
{
// nop
}
const_iterator
()
noexcept
:
storage_
(
nullptr
)
{
// nop
}
const_iterator
(
const
const_iterator
&
)
=
default
;
const_iterator
&
operator
=
(
const
const_iterator
&
)
=
default
;
json_value
value
()
const
noexcept
{
return
json_value
{
std
::
addressof
(
*
iter_
),
storage_
};
}
json_value
operator
*
()
const
noexcept
{
return
value
();
}
const_iterator
&
operator
++
()
noexcept
{
++
iter_
;
return
*
this
;
}
const_iterator
operator
++
(
int
)
noexcept
{
return
{
iter_
++
,
storage_
};
}
bool
equal_to
(
const
const_iterator
&
other
)
const
noexcept
{
return
iter_
==
other
.
iter_
;
}
private:
detail
::
json
::
value
::
array
::
const_iterator
iter_
;
detail
::
json
::
storage
*
storage_
;
};
// -- constructors, destructors, and assignment operators --------------------
json_array
()
noexcept
:
arr_
(
detail
::
json
::
empty_array
())
{
// nop
}
json_array
(
json_array
&&
)
noexcept
=
default
;
json_array
(
const
json_array
&
)
noexcept
=
default
;
json_array
&
operator
=
(
json_array
&&
)
noexcept
=
default
;
json_array
&
operator
=
(
const
json_array
&
)
noexcept
=
default
;
// -- properties -------------------------------------------------------------
/// Checks whether the array has no members.
bool
empty
()
const
noexcept
{
return
arr_
->
empty
();
}
/// Alias for @c empty.
bool
is_empty
()
const
noexcept
{
return
empty
();
}
/// Returns the number of key-value pairs in this array.
size_t
size
()
const
noexcept
{
return
arr_
->
size
();
}
const_iterator
begin
()
const
noexcept
{
return
{
arr_
->
begin
(),
storage_
.
get
()};
}
const_iterator
end
()
const
noexcept
{
return
{
arr_
->
end
(),
storage_
.
get
()};
}
// -- serialization ----------------------------------------------------------
template
<
class
Inspector
>
friend
bool
inspect
(
Inspector
&
inspector
,
json_array
&
arr
)
{
if
constexpr
(
Inspector
::
is_loading
)
{
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
auto
*
internal_arr
=
detail
::
json
::
make_array
(
storage
);
if
(
!
detail
::
json
::
load
(
inspector
,
*
internal_arr
,
storage
))
return
false
;
arr
=
json_array
{
internal_arr
,
std
::
move
(
storage
)};
return
true
;
}
else
{
return
detail
::
json
::
save
(
inspector
,
*
arr
.
arr_
);
}
}
private:
json_array
(
const
detail
::
json
::
value
::
array
*
obj
,
detail
::
json
::
storage_ptr
sptr
)
noexcept
:
arr_
(
obj
),
storage_
(
sptr
)
{
// nop
}
const
detail
::
json
::
value
::
array
*
arr_
=
nullptr
;
detail
::
json
::
storage_ptr
storage_
;
};
inline
bool
operator
==
(
const
json_array
::
const_iterator
&
lhs
,
const
json_array
::
const_iterator
&
rhs
)
noexcept
{
return
lhs
.
equal_to
(
rhs
);
}
inline
bool
operator
!=
(
const
json_array
::
const_iterator
&
lhs
,
const
json_array
::
const_iterator
&
rhs
)
noexcept
{
return
!
lhs
.
equal_to
(
rhs
);
}
inline
bool
operator
==
(
const
json_array
&
lhs
,
const
json_array
&
rhs
)
noexcept
{
return
std
::
equal
(
lhs
.
begin
(),
lhs
.
end
(),
rhs
.
begin
(),
rhs
.
end
());
}
inline
bool
operator
!=
(
const
json_array
&
lhs
,
const
json_array
&
rhs
)
noexcept
{
return
!
(
lhs
==
rhs
);
}
}
// namespace caf
libcaf_core/caf/json_object.hpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#pragma once
#include "caf/detail/core_export.hpp"
#include "caf/detail/json.hpp"
#include "caf/fwd.hpp"
#include "caf/json_value.hpp"
#include <iterator>
namespace
caf
{
/// Represents a JSON object.
class
CAF_CORE_EXPORT
json_object
{
public:
// -- friends ----------------------------------------------------------------
friend
class
json_value
;
// -- member types -----------------------------------------------------------
class
const_iterator
{
public:
using
difference_type
=
ptrdiff_t
;
using
value_type
=
std
::
pair
<
std
::
string_view
,
json_value
>
;
using
pointer
=
value_type
*
;
using
reference
=
value_type
&
;
using
iterator_category
=
std
::
forward_iterator_tag
;
const_iterator
(
detail
::
json
::
value
::
object
::
const_iterator
iter
,
detail
::
json
::
storage
*
storage
)
:
iter_
(
iter
),
storage_
(
storage
)
{
// nop
}
const_iterator
()
noexcept
=
default
;
const_iterator
(
const
const_iterator
&
)
=
default
;
const_iterator
&
operator
=
(
const
const_iterator
&
)
=
default
;
std
::
string_view
key
()
const
noexcept
{
return
iter_
->
key
;
}
json_value
value
()
const
noexcept
{
return
json_value
{
iter_
->
val
,
storage_
};
}
value_type
operator
*
()
const
noexcept
{
return
{
key
(),
value
()};
}
const_iterator
&
operator
++
()
noexcept
{
++
iter_
;
return
*
this
;
}
const_iterator
operator
++
(
int
)
noexcept
{
return
{
iter_
++
,
storage_
};
}
bool
equal_to
(
const
const_iterator
&
other
)
const
noexcept
{
return
iter_
==
other
.
iter_
;
}
private:
detail
::
json
::
value
::
object
::
const_iterator
iter_
;
detail
::
json
::
storage
*
storage_
=
nullptr
;
};
// -- constructors, destructors, and assignment operators --------------------
json_object
()
noexcept
:
obj_
(
detail
::
json
::
empty_object
())
{
// nop
}
json_object
(
json_object
&&
)
noexcept
=
default
;
json_object
(
const
json_object
&
)
noexcept
=
default
;
json_object
&
operator
=
(
json_object
&&
)
noexcept
=
default
;
json_object
&
operator
=
(
const
json_object
&
)
noexcept
=
default
;
// -- properties -------------------------------------------------------------
/// Checks whether the object has no members.
bool
empty
()
const
noexcept
{
return
!
obj_
||
obj_
->
empty
();
}
/// Alias for @c empty.
bool
is_empty
()
const
noexcept
{
return
empty
();
}
/// Returns the number of key-value pairs in this object.
size_t
size
()
const
noexcept
{
return
obj_
?
obj_
->
size
()
:
0u
;
}
/// Returns the value for @p key or an @c undefined value if the object does
/// not contain a value for @p key.
json_value
value
(
std
::
string_view
key
)
const
;
const_iterator
begin
()
const
noexcept
{
return
{
obj_
->
begin
(),
storage_
.
get
()};
}
const_iterator
end
()
const
noexcept
{
return
{
obj_
->
end
(),
storage_
.
get
()};
}
// -- serialization ----------------------------------------------------------
template
<
class
Inspector
>
friend
bool
inspect
(
Inspector
&
inspector
,
json_object
&
obj
)
{
if
constexpr
(
Inspector
::
is_loading
)
{
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
auto
*
internal_obj
=
detail
::
json
::
make_object
(
storage
);
if
(
!
detail
::
json
::
load
(
inspector
,
*
internal_obj
,
storage
))
return
false
;
obj
=
json_object
{
internal_obj
,
std
::
move
(
storage
)};
return
true
;
}
else
{
return
detail
::
json
::
save
(
inspector
,
*
obj
.
obj_
);
}
}
private:
json_object
(
const
detail
::
json
::
value
::
object
*
obj
,
detail
::
json
::
storage_ptr
sptr
)
noexcept
:
obj_
(
obj
),
storage_
(
sptr
)
{
// nop
}
const
detail
::
json
::
value
::
object
*
obj_
=
nullptr
;
detail
::
json
::
storage_ptr
storage_
;
};
inline
bool
operator
==
(
const
json_object
::
const_iterator
&
lhs
,
const
json_object
::
const_iterator
&
rhs
)
noexcept
{
return
lhs
.
equal_to
(
rhs
);
}
inline
bool
operator
!=
(
const
json_object
::
const_iterator
&
lhs
,
const
json_object
::
const_iterator
&
rhs
)
noexcept
{
return
!
lhs
.
equal_to
(
rhs
);
}
inline
bool
operator
==
(
const
json_object
&
lhs
,
const
json_object
&
rhs
)
noexcept
{
return
std
::
equal
(
lhs
.
begin
(),
lhs
.
end
(),
rhs
.
begin
(),
rhs
.
end
());
}
inline
bool
operator
!=
(
const
json_object
&
lhs
,
const
json_object
&
rhs
)
noexcept
{
return
!
(
lhs
==
rhs
);
}
}
// namespace caf
libcaf_core/caf/json_value.hpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#pragma once
#include "caf/detail/core_export.hpp"
#include "caf/detail/json.hpp"
#include "caf/fwd.hpp"
#include "caf/make_counted.hpp"
#include <string>
#include <string_view>
namespace
caf
{
/// Represents an immutable JSON value.
class
CAF_CORE_EXPORT
json_value
{
public:
// -- constructors, destructors, and assignment operators --------------------
json_value
()
noexcept
:
val_
(
detail
::
json
::
null_value
())
{
// nop
}
json_value
(
const
detail
::
json
::
value
*
val
,
detail
::
json
::
storage_ptr
sptr
)
noexcept
:
val_
(
val
),
storage_
(
sptr
)
{
// nop
}
json_value
(
json_value
&&
)
noexcept
=
default
;
json_value
(
const
json_value
&
)
noexcept
=
default
;
json_value
&
operator
=
(
json_value
&&
)
noexcept
=
default
;
json_value
&
operator
=
(
const
json_value
&
)
noexcept
=
default
;
// -- factories --------------------------------------------------------------
static
json_value
undefined
()
noexcept
{
return
json_value
{
detail
::
json
::
undefined_value
(),
nullptr
};
}
// -- properties -------------------------------------------------------------
/// Checks whether the value is @c null.
bool
is_null
()
const
noexcept
{
return
val_
->
is_null
();
}
/// Checks whether the value is undefined. This special state indicates that a
/// previous key lookup failed.
bool
is_undefined
()
const
noexcept
{
return
val_
->
is_undefined
();
}
/// Checks whether the value is an @c int64_t.
bool
is_integer
()
const
noexcept
{
return
val_
->
is_integer
();
}
/// Checks whether the value is a @c double.
bool
is_double
()
const
noexcept
{
return
val_
->
is_double
();
}
/// Checks whether the value is a number, i.e., an @c int64_t or a @c double.
bool
is_number
()
const
noexcept
{
return
is_integer
()
||
is_double
();
}
/// Checks whether the value is a @c bool.
bool
is_bool
()
const
noexcept
{
return
val_
->
is_bool
();
}
/// Checks whether the value is a JSON string (@c std::string_view).
bool
is_string
()
const
noexcept
{
return
val_
->
is_string
();
}
/// Checks whether the value is an JSON array.
bool
is_array
()
const
noexcept
{
return
val_
->
is_array
();
}
/// Checks whether the value is a JSON object.
bool
is_object
()
const
noexcept
{
return
val_
->
is_object
();
}
// -- conversion -------------------------------------------------------------
int64_t
to_integer
(
int64_t
fallback
=
0
)
const
;
double
to_double
(
double
fallback
=
0.0
)
const
;
bool
to_bool
(
bool
fallback
=
false
)
const
;
std
::
string_view
to_string
()
const
;
std
::
string_view
to_string
(
std
::
string_view
fallback
)
const
;
json_array
to_array
()
const
;
json_array
to_array
(
json_array
fallback
)
const
;
json_object
to_object
()
const
;
json_object
to_object
(
json_object
fallback
)
const
;
// -- comparison -------------------------------------------------------------
bool
equal_to
(
const
json_value
&
other
)
const
noexcept
;
// -- parsing ----------------------------------------------------------------
/// Attempts to parse @p str as JSON input into a self-contained value.
static
expected
<
json_value
>
parse
(
std
::
string_view
str
);
/// Attempts to parse @p str as JSON input into a value that avoids copies
/// where possible by pointing into @p str.
/// @warning The returned @ref json_value may hold pointers into @p str. Thus,
/// the input *must* outlive the @ref json_value and any other JSON
/// objects created from that value.
static
expected
<
json_value
>
parse_shallow
(
std
::
string_view
str
);
/// Attempts to parse @p str as JSON input. Decodes JSON in place and points
/// back into the @p str for all strings in the JSON input.
/// @warning The returned @ref json_value may hold pointers into @p str. Thus,
/// the input *must* outlive the @ref json_value and any other JSON
/// objects created from that value.
static
expected
<
json_value
>
parse_in_situ
(
std
::
string
&
str
);
// -- serialization ----------------------------------------------------------
template
<
class
Inspector
>
friend
bool
inspect
(
Inspector
&
inspector
,
json_value
&
val
)
{
if
constexpr
(
Inspector
::
is_loading
)
{
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
auto
*
internal_val
=
detail
::
json
::
make_value
(
storage
);
if
(
!
detail
::
json
::
load
(
inspector
,
*
internal_val
,
storage
))
return
false
;
val
=
json_value
{
internal_val
,
std
::
move
(
storage
)};
return
true
;
}
else
{
return
detail
::
json
::
save
(
inspector
,
*
val
.
val_
);
}
}
private:
const
detail
::
json
::
value
*
val_
;
detail
::
json
::
storage_ptr
storage_
;
};
inline
bool
operator
==
(
const
json_value
&
lhs
,
const
json_value
&
rhs
)
{
return
lhs
.
equal_to
(
rhs
);
}
inline
bool
operator
!=
(
const
json_value
&
lhs
,
const
json_value
&
rhs
)
{
return
!
(
lhs
==
rhs
);
}
}
// namespace caf
libcaf_core/caf/parser_state.hpp
View file @
50984474
...
@@ -16,6 +16,8 @@ namespace caf {
...
@@ -16,6 +16,8 @@ namespace caf {
/// Stores all information necessary for implementing an FSM-based parser.
/// Stores all information necessary for implementing an FSM-based parser.
template
<
class
Iterator
,
class
Sentinel
>
template
<
class
Iterator
,
class
Sentinel
>
struct
parser_state
{
struct
parser_state
{
using
iterator_type
=
Iterator
;
/// Current position of the parser.
/// Current position of the parser.
Iterator
i
;
Iterator
i
;
...
@@ -139,4 +141,7 @@ auto make_error(const parser_state<Iterator, Sentinel>& ps, Ts&&... xs)
...
@@ -139,4 +141,7 @@ auto make_error(const parser_state<Iterator, Sentinel>& ps, Ts&&... xs)
/// Specialization for parsers operating on string views.
/// Specialization for parsers operating on string views.
using
string_parser_state
=
parser_state
<
std
::
string_view
::
iterator
>
;
using
string_parser_state
=
parser_state
<
std
::
string_view
::
iterator
>
;
/// Specialization for parsers operating on mutable character sequences.
using
mutable_string_parser_state
=
parser_state
<
char
*>
;
}
// namespace caf
}
// namespace caf
libcaf_core/caf/type_id.hpp
View file @
50984474
...
@@ -405,7 +405,6 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
...
@@ -405,7 +405,6 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
cow_string
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
cow_string
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
cow_u16string
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
cow_u16string
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
cow_u32string
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
cow_u32string
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
dictionary
<
caf
::
config_value
>
)
)
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
down_msg
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
down_msg
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
error
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
error
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
exit_msg
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
exit_msg
))
...
@@ -419,6 +418,9 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
...
@@ -419,6 +418,9 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
ipv6_address
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
ipv6_address
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
ipv6_endpoint
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
ipv6_endpoint
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
ipv6_subnet
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
ipv6_subnet
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
json_array
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
json_object
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
json_value
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
message
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
message
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
message_id
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
message_id
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
node_down_msg
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
node_down_msg
))
...
@@ -426,6 +428,7 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
...
@@ -426,6 +428,7 @@ CAF_BEGIN_TYPE_ID_BLOCK(core_module, 0)
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
none_t
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
none_t
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
pec
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
pec
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
sec
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
sec
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
settings
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
shared_action_ptr
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
shared_action_ptr
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
stream
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
stream
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
stream_abort_msg
))
CAF_ADD_TYPE_ID
(
core_module
,
(
caf
::
stream_abort_msg
))
...
...
libcaf_core/src/detail/json.cpp
View file @
50984474
This diff is collapsed.
Click to expand it.
libcaf_core/src/init_global_meta_objects.cpp
View file @
50984474
...
@@ -21,6 +21,9 @@
...
@@ -21,6 +21,9 @@
#include "caf/ipv6_address.hpp"
#include "caf/ipv6_address.hpp"
#include "caf/ipv6_endpoint.hpp"
#include "caf/ipv6_endpoint.hpp"
#include "caf/ipv6_subnet.hpp"
#include "caf/ipv6_subnet.hpp"
#include "caf/json_array.hpp"
#include "caf/json_object.hpp"
#include "caf/json_value.hpp"
#include "caf/message.hpp"
#include "caf/message.hpp"
#include "caf/message_id.hpp"
#include "caf/message_id.hpp"
#include "caf/node_id.hpp"
#include "caf/node_id.hpp"
...
...
libcaf_core/src/json_object.cpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#include "caf/json_object.hpp"
namespace
caf
{
// -- properties ---------------------------------------------------------------
json_value
json_object
::
value
(
std
::
string_view
key
)
const
{
auto
pred
=
[
key
](
const
auto
&
member
)
{
return
member
.
key
==
key
;
};
auto
i
=
std
::
find_if
(
obj_
->
begin
(),
obj_
->
end
(),
pred
);
if
(
i
!=
obj_
->
end
())
{
return
{
i
->
val
,
storage_
};
}
return
json_value
::
undefined
();
}
}
// namespace caf
libcaf_core/src/json_reader.cpp
View file @
50984474
...
@@ -145,7 +145,7 @@ json_reader::~json_reader() {
...
@@ -145,7 +145,7 @@ json_reader::~json_reader() {
bool
json_reader
::
load
(
std
::
string_view
json_text
)
{
bool
json_reader
::
load
(
std
::
string_view
json_text
)
{
reset
();
reset
();
string_parser_state
ps
{
json_text
.
begin
(),
json_text
.
end
()};
string_parser_state
ps
{
json_text
.
begin
(),
json_text
.
end
()};
root_
=
detail
::
json
::
parse
(
ps
,
&
buf_
);
root_
=
detail
::
json
::
parse
_shallow
(
ps
,
&
buf_
);
if
(
ps
.
code
!=
pec
::
success
)
{
if
(
ps
.
code
!=
pec
::
success
)
{
set_error
(
make_error
(
ps
));
set_error
(
make_error
(
ps
));
st_
=
nullptr
;
st_
=
nullptr
;
...
...
libcaf_core/src/json_value.cpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#include "caf/json_value.hpp"
#include "caf/expected.hpp"
#include "caf/json_array.hpp"
#include "caf/json_object.hpp"
#include "caf/make_counted.hpp"
#include "caf/parser_state.hpp"
namespace
caf
{
// -- conversion ---------------------------------------------------------------
int64_t
json_value
::
to_integer
(
int64_t
fallback
)
const
{
if
(
is_integer
())
{
return
std
::
get
<
int64_t
>
(
val_
->
data
);
}
if
(
is_double
())
{
return
static_cast
<
int64_t
>
(
std
::
get
<
double
>
(
val_
->
data
));
}
return
fallback
;
}
double
json_value
::
to_double
(
double
fallback
)
const
{
if
(
is_double
())
{
return
std
::
get
<
double
>
(
val_
->
data
);
}
if
(
is_integer
())
{
return
static_cast
<
double
>
(
std
::
get
<
int64_t
>
(
val_
->
data
));
}
return
fallback
;
}
bool
json_value
::
to_bool
(
bool
fallback
)
const
{
if
(
is_bool
())
{
return
std
::
get
<
bool
>
(
val_
->
data
);
}
return
fallback
;
}
std
::
string_view
json_value
::
to_string
()
const
{
return
to_string
(
std
::
string_view
{});
}
std
::
string_view
json_value
::
to_string
(
std
::
string_view
fallback
)
const
{
if
(
is_string
())
{
return
std
::
get
<
std
::
string_view
>
(
val_
->
data
);
}
return
fallback
;
}
json_object
json_value
::
to_object
()
const
{
return
to_object
(
json_object
{});
}
json_object
json_value
::
to_object
(
json_object
fallback
)
const
{
if
(
is_object
())
{
return
json_object
{
&
std
::
get
<
detail
::
json
::
object
>
(
val_
->
data
),
storage_
};
}
return
fallback
;
}
json_array
json_value
::
to_array
()
const
{
return
to_array
(
json_array
{});
}
json_array
json_value
::
to_array
(
json_array
fallback
)
const
{
if
(
is_array
())
{
return
json_array
{
&
std
::
get
<
detail
::
json
::
array
>
(
val_
->
data
),
storage_
};
}
return
fallback
;
}
// -- comparison ---------------------------------------------------------------
bool
json_value
::
equal_to
(
const
json_value
&
other
)
const
noexcept
{
if
(
val_
==
other
.
val_
)
{
return
true
;
}
if
(
val_
!=
nullptr
&&
other
.
val_
!=
nullptr
)
{
return
*
val_
==
*
other
.
val_
;
}
return
false
;
}
// -- parsing ------------------------------------------------------------------
expected
<
json_value
>
json_value
::
parse
(
std
::
string_view
str
)
{
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
auto
root
=
detail
::
json
::
parse
(
ps
,
&
storage
->
buf
);
if
(
ps
.
code
!=
pec
::
success
)
{
return
{
make_error
(
ps
)};
}
else
{
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
}
}
expected
<
json_value
>
json_value
::
parse_shallow
(
std
::
string_view
str
)
{
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
string_parser_state
ps
{
str
.
begin
(),
str
.
end
()};
auto
root
=
detail
::
json
::
parse_shallow
(
ps
,
&
storage
->
buf
);
if
(
ps
.
code
!=
pec
::
success
)
{
return
{
make_error
(
ps
)};
}
else
{
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
}
}
expected
<
json_value
>
json_value
::
parse_in_situ
(
std
::
string
&
str
)
{
auto
storage
=
make_counted
<
detail
::
json
::
storage
>
();
mutable_string_parser_state
ps
{
str
.
data
(),
str
.
data
()
+
str
.
size
()};
auto
root
=
detail
::
json
::
parse_in_situ
(
ps
,
&
storage
->
buf
);
if
(
ps
.
code
!=
pec
::
success
)
{
return
{
make_error
(
ps
)};
}
else
{
return
{
json_value
{
root
,
std
::
move
(
storage
)}};
}
}
}
// namespace caf
libcaf_core/test/core-test.hpp
View file @
50984474
#pragma once
#pragma once
#include "caf/binary_deserializer.hpp"
#include "caf/binary_serializer.hpp"
#include "caf/byte_buffer.hpp"
#include "caf/cow_vector.hpp"
#include "caf/cow_vector.hpp"
#include "caf/fwd.hpp"
#include "caf/fwd.hpp"
#include "caf/result.hpp"
#include "caf/result.hpp"
...
@@ -13,6 +16,32 @@
...
@@ -13,6 +16,32 @@
#include <string>
#include <string>
#include <utility>
#include <utility>
// -- utility for testing serialization round-trips ----------------------------
template
<
class
T
>
T
deep_copy
(
const
T
&
val
)
{
using
namespace
std
::
literals
;
caf
::
byte_buffer
buf
;
{
caf
::
binary_serializer
sink
{
nullptr
,
buf
};
if
(
!
sink
.
apply
(
val
))
{
auto
msg
=
"serialization failed in deep_copy: "
s
;
msg
+=
to_string
(
sink
.
get_error
());
CAF_RAISE_ERROR
(
msg
.
c_str
());
}
}
auto
result
=
T
{};
{
caf
::
binary_deserializer
sink
{
nullptr
,
buf
};
if
(
!
sink
.
apply
(
result
))
{
auto
msg
=
"deserialization failed in deep_copy: "
s
;
msg
+=
to_string
(
sink
.
get_error
());
CAF_RAISE_ERROR
(
msg
.
c_str
());
}
}
return
result
;
}
// -- forward declarations for all unit test suites ----------------------------
// -- forward declarations for all unit test suites ----------------------------
using
float_actor
=
caf
::
typed_actor
<
caf
::
result
<
void
>
(
float
)
>
;
using
float_actor
=
caf
::
typed_actor
<
caf
::
result
<
void
>
(
float
)
>
;
...
...
libcaf_core/test/detail/json.cpp
View file @
50984474
...
@@ -106,6 +106,12 @@ void stringify(std::string& str, size_t, detail::json::null_t) {
...
@@ -106,6 +106,12 @@ void stringify(std::string& str, size_t, detail::json::null_t) {
str
+=
"null"
;
str
+=
"null"
;
}
}
void
stringify
(
std
::
string
&
str
,
size_t
,
detail
::
json
::
undefined_t
)
{
// The parser never emits undefined objects, but we still need to provide an
// overload for this type.
str
+=
"null"
;
}
void
stringify
(
std
::
string
&
str
,
size_t
indent
,
const
detail
::
json
::
array
&
xs
)
{
void
stringify
(
std
::
string
&
str
,
size_t
indent
,
const
detail
::
json
::
array
&
xs
)
{
if
(
xs
.
empty
())
{
if
(
xs
.
empty
())
{
str
+=
"[]"
;
str
+=
"[]"
;
...
...
libcaf_core/test/json_array.cpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE json_array
#include "caf/json_array.hpp"
#include "core-test.hpp"
#include "caf/json_array.hpp"
#include "caf/json_value.hpp"
using
namespace
caf
;
using
namespace
std
::
literals
;
TEST_CASE
(
"default-constructed"
)
{
auto
arr
=
json_array
{};
CHECK
(
arr
.
empty
());
CHECK
(
arr
.
is_empty
());
CHECK
(
arr
.
begin
()
==
arr
.
end
());
CHECK_EQ
(
arr
.
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
arr
),
arr
);
}
TEST_CASE
(
"from empty array"
)
{
auto
arr
=
json_value
::
parse
(
"[]"
)
->
to_array
();
CHECK
(
arr
.
empty
());
CHECK
(
arr
.
is_empty
());
CHECK
(
arr
.
begin
()
==
arr
.
end
());
CHECK_EQ
(
arr
.
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
arr
),
arr
);
}
TEST_CASE
(
"from non-empty array"
)
{
auto
arr
=
json_value
::
parse
(
R"_([1, "two", 3.0])_"
)
->
to_array
();
CHECK
(
!
arr
.
empty
());
CHECK
(
!
arr
.
is_empty
());
CHECK
(
arr
.
begin
()
!=
arr
.
end
());
REQUIRE_EQ
(
arr
.
size
(),
3u
);
CHECK_EQ
((
*
arr
.
begin
()).
to_integer
(),
1
);
std
::
vector
<
json_value
>
vals
;
for
(
const
auto
&
val
:
arr
)
{
vals
.
emplace_back
(
val
);
}
REQUIRE_EQ
(
vals
.
size
(),
3u
);
CHECK_EQ
(
vals
[
0
].
to_integer
(),
1
);
CHECK_EQ
(
vals
[
1
].
to_string
(),
"two"
);
CHECK_EQ
(
vals
[
2
].
to_double
(),
3.0
);
CHECK_EQ
(
deep_copy
(
arr
),
arr
);
}
libcaf_core/test/json_object.cpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE json_object
#include "caf/json_object.hpp"
#include "core-test.hpp"
#include "caf/json_array.hpp"
#include "caf/json_value.hpp"
using
namespace
caf
;
using
namespace
std
::
literals
;
TEST_CASE
(
"default-constructed"
)
{
auto
obj
=
json_object
{};
CHECK
(
obj
.
empty
());
CHECK
(
obj
.
is_empty
());
CHECK
(
obj
.
begin
()
==
obj
.
end
());
CHECK_EQ
(
obj
.
size
(),
0u
);
CHECK
(
obj
.
value
(
"foo"
).
is_undefined
());
CHECK_EQ
(
deep_copy
(
obj
),
obj
);
}
TEST_CASE
(
"from empty object"
)
{
auto
obj
=
json_value
::
parse
(
"{}"
)
->
to_object
();
CHECK
(
obj
.
empty
());
CHECK
(
obj
.
is_empty
());
CHECK
(
obj
.
begin
()
==
obj
.
end
());
CHECK_EQ
(
obj
.
size
(),
0u
);
CHECK
(
obj
.
value
(
"foo"
).
is_undefined
());
CHECK_EQ
(
deep_copy
(
obj
),
obj
);
}
TEST_CASE
(
"from non-empty object"
)
{
auto
obj
=
json_value
::
parse
(
R"_({"a": "one", "b": 2})_"
)
->
to_object
();
CHECK
(
!
obj
.
empty
());
CHECK
(
!
obj
.
is_empty
());
CHECK
(
obj
.
begin
()
!=
obj
.
end
());
REQUIRE_EQ
(
obj
.
size
(),
2u
);
CHECK_EQ
(
obj
.
begin
().
key
(),
"a"
);
CHECK_EQ
(
obj
.
begin
().
value
().
to_string
(),
"one"
);
CHECK_EQ
(
obj
.
value
(
"a"
).
to_string
(),
"one"
);
CHECK_EQ
(
obj
.
value
(
"b"
).
to_integer
(),
2
);
CHECK
(
obj
.
value
(
"c"
).
is_undefined
());
std
::
vector
<
std
::
pair
<
std
::
string_view
,
json_value
>>
vals
;
for
(
const
auto
&
val
:
obj
)
{
vals
.
emplace_back
(
val
);
}
REQUIRE_EQ
(
vals
.
size
(),
2u
);
CHECK_EQ
(
vals
[
0
].
first
,
"a"
);
CHECK_EQ
(
vals
[
0
].
second
.
to_string
(),
"one"
);
CHECK_EQ
(
vals
[
1
].
first
,
"b"
);
CHECK_EQ
(
vals
[
1
].
second
.
to_integer
(),
2
);
CHECK_EQ
(
deep_copy
(
obj
),
obj
);
}
libcaf_core/test/json_value.cpp
0 → 100644
View file @
50984474
// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.
#define CAF_SUITE json_value
#include "caf/json_value.hpp"
#include "core-test.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/binary_serializer.hpp"
#include "caf/json_array.hpp"
#include "caf/json_object.hpp"
using
namespace
caf
;
using
namespace
std
::
literals
;
TEST_CASE
(
"default-constructed"
)
{
auto
val
=
json_value
{};
CHECK
(
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
!
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
!
val
.
is_array
());
CHECK
(
!
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
0
);
CHECK_EQ
(
val
.
to_double
(),
0.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from undefined"
)
{
auto
val
=
json_value
::
undefined
();
CHECK
(
!
val
.
is_null
());
CHECK
(
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
!
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
!
val
.
is_array
());
CHECK
(
!
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
0
);
CHECK_EQ
(
val
.
to_double
(),
0.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from integer"
)
{
auto
val
=
unbox
(
json_value
::
parse
(
"42"
));
CHECK
(
!
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
!
val
.
is_array
());
CHECK
(
!
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
42
);
CHECK_EQ
(
val
.
to_double
(),
42.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from double"
)
{
auto
val
=
unbox
(
json_value
::
parse
(
"42.0"
));
CHECK
(
!
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
val
.
is_double
());
CHECK
(
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
!
val
.
is_array
());
CHECK
(
!
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
42
);
CHECK_EQ
(
val
.
to_double
(),
42.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from bool"
)
{
auto
val
=
unbox
(
json_value
::
parse
(
"true"
));
CHECK
(
!
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
!
val
.
is_number
());
CHECK
(
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
!
val
.
is_array
());
CHECK
(
!
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
0
);
CHECK_EQ
(
val
.
to_double
(),
0.0
);
CHECK_EQ
(
val
.
to_bool
(),
true
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
MESSAGE
(
deep_to_string
(
val
));
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from string"
)
{
auto
val
=
unbox
(
json_value
::
parse
(
R"_("Hello, world!")_"
));
CHECK
(
!
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
!
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
val
.
is_string
());
CHECK
(
!
val
.
is_array
());
CHECK
(
!
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
0
);
CHECK_EQ
(
val
.
to_double
(),
0.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
"Hello, world!"
sv
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from empty array"
)
{
auto
val
=
unbox
(
json_value
::
parse
(
"[]"
));
CHECK
(
!
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
!
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
val
.
is_array
());
CHECK
(
!
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
0
);
CHECK_EQ
(
val
.
to_double
(),
0.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_array
().
size
(),
0u
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from non-empty array"
)
{
auto
val
=
unbox
(
json_value
::
parse
(
"[1, 2, 3]"
));
CHECK
(
!
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
!
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
val
.
is_array
());
CHECK
(
!
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
0
);
CHECK_EQ
(
val
.
to_double
(),
0.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_array
().
size
(),
3u
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from empty object"
)
{
auto
val
=
unbox
(
json_value
::
parse
(
"{}"
));
CHECK
(
!
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
!
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
!
val
.
is_array
());
CHECK
(
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
0
);
CHECK_EQ
(
val
.
to_double
(),
0.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_object
().
size
(),
0u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
TEST_CASE
(
"from non-empty object"
)
{
auto
val
=
unbox
(
json_value
::
parse
(
R"_({"foo": "bar"})_"
));
CHECK
(
!
val
.
is_null
());
CHECK
(
!
val
.
is_undefined
());
CHECK
(
!
val
.
is_integer
());
CHECK
(
!
val
.
is_double
());
CHECK
(
!
val
.
is_number
());
CHECK
(
!
val
.
is_bool
());
CHECK
(
!
val
.
is_string
());
CHECK
(
!
val
.
is_array
());
CHECK
(
val
.
is_object
());
CHECK_EQ
(
val
.
to_integer
(),
0
);
CHECK_EQ
(
val
.
to_double
(),
0.0
);
CHECK_EQ
(
val
.
to_bool
(),
false
);
CHECK_EQ
(
val
.
to_string
(),
""
sv
);
CHECK_EQ
(
val
.
to_object
().
size
(),
1u
);
CHECK_EQ
(
deep_copy
(
val
),
val
);
}
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