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
e74fd805
Commit
e74fd805
authored
Apr 19, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1085
parents
65f2dc01
7e38a24f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
135 additions
and
20 deletions
+135
-20
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+1
-0
libcaf_core/caf/detail/type_id_list_builder.hpp
libcaf_core/caf/detail/type_id_list_builder.hpp
+2
-4
libcaf_core/caf/message_builder.hpp
libcaf_core/caf/message_builder.hpp
+4
-1
libcaf_core/caf/type_id_list.hpp
libcaf_core/caf/type_id_list.hpp
+7
-1
libcaf_core/src/detail/type_id_list_builder.cpp
libcaf_core/src/detail/type_id_list_builder.cpp
+15
-10
libcaf_core/src/message_builder.cpp
libcaf_core/src/message_builder.cpp
+37
-4
libcaf_core/test/message_builder.cpp
libcaf_core/test/message_builder.cpp
+69
-0
No files found.
libcaf_core/CMakeLists.txt
View file @
e74fd805
...
...
@@ -276,6 +276,7 @@ caf_add_test_suites(caf-core-test
mailbox_element
make_config_value_field
message
message_builder
message_id
message_lifetime
metaprogramming
...
...
libcaf_core/caf/detail/type_id_list_builder.hpp
View file @
e74fd805
...
...
@@ -45,12 +45,10 @@ public:
type_id_t
operator
[](
size_t
index
)
const
noexcept
;
/// Convertes the internal buffer to a ::type_id_list and returns it.
/// @pre `push_back` was called at least once
type_id_list
move_to_list
();
type_id_list
move_to_list
()
noexcept
;
/// Convertes the internal buffer to a ::type_id_list and returns it.
/// @pre `push_back` was called at least once
type_id_list
copy_to_list
();
type_id_list
copy_to_list
()
const
;
void
clear
()
noexcept
{
if
(
storage_
)
...
...
libcaf_core/caf/message_builder.hpp
View file @
e74fd805
...
...
@@ -23,6 +23,7 @@
#include "caf/detail/core_export.hpp"
#include "caf/detail/implicit_conversions.hpp"
#include "caf/detail/message_builder_element.hpp"
#include "caf/detail/padded_size.hpp"
#include "caf/detail/type_id_list_builder.hpp"
#include "caf/fwd.hpp"
#include "caf/message.hpp"
...
...
@@ -61,6 +62,7 @@ public:
using
namespace
detail
;
using
value_type
=
strip_and_convert_t
<
T
>
;
static_assert
(
sendable
<
value_type
>
);
storage_size_
+=
padded_size_v
<
value_type
>
;
types_
.
push_back
(
type_id_v
<
value_type
>
);
elements_
.
emplace_back
(
make_message_builder_element
(
std
::
forward
<
T
>
(
x
)));
return
*
this
;
...
...
@@ -91,7 +93,7 @@ public:
/// Converts the buffer to an actual message object and transfers
/// ownership of the data to it, leaving this object in an invalid state.
/// @warning Calling *any* member function on this object afterwards
/// is undefined behavior
(dereferencing a `nullptr`)
/// is undefined behavior
.
message
move_to_message
();
/// Removes all elements from the buffer.
...
...
@@ -108,6 +110,7 @@ public:
}
private:
size_t
storage_size_
=
0
;
detail
::
type_id_list_builder
types_
;
std
::
vector
<
detail
::
message_builder_element_ptr
>
elements_
;
};
...
...
libcaf_core/caf/type_id_list.hpp
View file @
e74fd805
...
...
@@ -69,7 +69,13 @@ public:
/// Compares this list to `other`.
int
compare
(
type_id_list
other
)
const
noexcept
{
return
memcmp
(
data_
,
other
.
data_
,
(
size
()
+
1
)
*
sizeof
(
type_id_t
));
// These conversions are safe, because the size is stored in 16 bits.
int
s1
=
data_
[
0
];
int
s2
=
other
.
data_
[
0
];
int
diff
=
s1
-
s2
;
if
(
diff
==
0
)
return
memcmp
(
begin
(),
other
.
begin
(),
s1
*
sizeof
(
type_id_t
));
return
diff
;
}
/// Returns an iterator to the first type ID.
...
...
libcaf_core/src/detail/type_id_list_builder.cpp
View file @
e74fd805
...
...
@@ -19,6 +19,7 @@
#include "caf/detail/type_id_list_builder.hpp"
#include <cstdint>
#include <cstdlib>
#include <mutex>
#include <unordered_set>
...
...
@@ -30,15 +31,17 @@ namespace caf::detail {
namespace
{
struct
dyn_type_id_list
{
dyn_type_id_list
(
type_id_t
*
storage
)
:
storage
(
storage
)
{
explicit
dyn_type_id_list
(
type_id_t
*
storage
)
noexcept
:
storage
(
storage
)
{
CAF_ASSERT
(
storage
!=
nullptr
);
auto
first
=
reinterpret_cast
<
const
uint8_t
*>
(
storage
);
auto
last
=
first
+
((
storage
[
0
]
+
1
)
*
sizeof
(
type_id_t
));
hash
=
caf
::
hash
::
fnv
<
size_t
>::
compute
(
make_span
(
first
,
last
));
}
dyn_type_id_list
(
dyn_type_id_list
&&
other
)
dyn_type_id_list
(
dyn_type_id_list
&&
other
)
noexcept
:
storage
(
other
.
storage
),
hash
(
other
.
hash
)
{
other
.
storage
=
nullptr
;
other
.
hash
=
0
;
}
~
dyn_type_id_list
()
{
...
...
@@ -49,7 +52,7 @@ struct dyn_type_id_list {
size_t
hash
;
};
bool
operator
==
(
const
dyn_type_id_list
&
x
,
const
dyn_type_id_list
&
y
)
{
bool
operator
==
(
const
dyn_type_id_list
&
x
,
const
dyn_type_id_list
&
y
)
noexcept
{
return
type_id_list
{
x
.
storage
}
==
type_id_list
{
y
.
storage
};
}
...
...
@@ -122,10 +125,11 @@ type_id_t type_id_list_builder::operator[](size_t index) const noexcept {
return
storage_
[
index
+
1
];
}
type_id_list
type_id_list_builder
::
move_to_list
()
{
if
(
size_
==
0
)
type_id_list
type_id_list_builder
::
move_to_list
()
noexcept
{
auto
list_size
=
size
();
if
(
list_size
==
0
)
return
make_type_id_list
();
storage_
[
0
]
=
static_cast
<
type_id_t
>
(
size
()
);
storage_
[
0
]
=
static_cast
<
type_id_t
>
(
list_size
);
// Transfer ownership of buffer into the global cache. If an equivalent list
// already exists, get_or_set_type_id_buf releases `ptr` and returns the old
// buffer.
...
...
@@ -134,15 +138,16 @@ type_id_list type_id_list_builder::move_to_list() {
return
type_id_list
{
get_or_set_type_id_buf
(
ptr
)};
}
type_id_list
type_id_list_builder
::
copy_to_list
()
{
if
(
size_
==
0
)
type_id_list
type_id_list_builder
::
copy_to_list
()
const
{
auto
list_size
=
size
();
if
(
list_size
==
0
)
return
make_type_id_list
();
storage_
[
0
]
=
static_cast
<
type_id_t
>
(
size
());
auto
vptr
=
malloc
(
size_
*
sizeof
(
type_id_t
));
if
(
vptr
==
nullptr
)
throw
std
::
bad_alloc
();
auto
copy
=
reinterpret_cast
<
type_id_t
*>
(
vptr
);
memcpy
(
copy
,
storage_
,
size_
*
sizeof
(
type_id_t
));
copy
[
0
]
=
static_cast
<
type_id_t
>
(
list_size
);
memcpy
(
copy
+
1
,
storage_
+
1
,
list_size
*
sizeof
(
type_id_t
));
return
type_id_list
{
get_or_set_type_id_buf
(
copy
)};
}
...
...
libcaf_core/src/message_builder.cpp
View file @
e74fd805
...
...
@@ -20,19 +20,52 @@
namespace
caf
{
namespace
{
using
namespace
detail
;
enum
to_msg_policy
{
move_msg
,
copy_msg
,
};
template
<
to_msg_policy
Policy
,
class
TypeListBuilder
,
class
ElementVector
>
message
to_message_impl
(
size_t
storage_size
,
TypeListBuilder
&
types
,
ElementVector
&
elements
)
{
if
(
storage_size
==
0
)
return
message
{};
auto
vptr
=
malloc
(
sizeof
(
message_data
)
+
storage_size
);
if
(
vptr
==
nullptr
)
throw
std
::
bad_alloc
();
message_data
*
raw_ptr
;
if
constexpr
(
Policy
==
move_msg
)
raw_ptr
=
new
(
vptr
)
message_data
(
types
.
move_to_list
());
else
raw_ptr
=
new
(
vptr
)
message_data
(
types
.
copy_to_list
());
intrusive_cow_ptr
<
message_data
>
ptr
{
raw_ptr
,
false
};
auto
storage
=
raw_ptr
->
storage
();
for
(
auto
&
element
:
elements
)
if
constexpr
(
Policy
==
move_msg
)
storage
=
element
->
move_init
(
storage
);
else
storage
=
element
->
copy_init
(
storage
);
return
message
{
std
::
move
(
ptr
)};
}
}
// namespace
void
message_builder
::
clear
()
noexcept
{
storage_size_
=
0
;
types_
.
clear
();
elements_
.
clear
();
}
message
message_builder
::
to_message
()
const
{
// TODO: implement me
return
{};
return
to_message_impl
<
copy_msg
>
(
storage_size_
,
types_
,
elements_
);
}
message
message_builder
::
move_to_message
()
{
// TODO: implement me
return
{};
return
to_message_impl
<
move_msg
>
(
storage_size_
,
types_
,
elements_
);
}
}
// namespace caf
libcaf_core/test/message_builder.cpp
0 → 100644
View file @
e74fd805
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2018 Dominik Charousset *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#define CAF_SUITE message_builder
#include "caf/message_builder.hpp"
#include "core-test.hpp"
#include <map>
#include <numeric>
#include <string>
#include <vector>
#include "caf/message.hpp"
#include "caf/type_id_list.hpp"
using
namespace
caf
;
#define STEP(message) \
CAF_MESSAGE(message); \
if (true)
CAF_TEST
(
message
builder
can
build
messages
incrermenetally
)
{
message_builder
builder
;
CAF_CHECK
(
builder
.
empty
());
CAF_CHECK
(
builder
.
to_message
().
empty
());
CAF_CHECK_EQUAL
(
builder
.
size
(),
0u
);
STEP
(
"after adding 1, the message is (1)"
)
{
builder
.
append
(
int32_t
{
1
});
auto
msg
=
builder
.
to_message
();
CAF_CHECK_EQUAL
(
builder
.
size
(),
1u
);
CAF_CHECK_EQUAL
(
msg
.
types
(),
make_type_id_list
<
int32_t
>
());
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
),
"(1)"
);
}
STEP
(
"after adding [2, 3], the message is (1, 2, 3)"
)
{
std
::
vector
<
int32_t
>
xs
{
2
,
3
};
builder
.
append
(
xs
.
begin
(),
xs
.
end
());
CAF_CHECK_EQUAL
(
builder
.
size
(),
3u
);
auto
msg
=
builder
.
to_message
();
CAF_CHECK_EQUAL
(
msg
.
types
(),
(
make_type_id_list
<
int32_t
,
int32_t
,
int32_t
>
()));
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t, int32_t, int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
),
"(1, 2, 3)"
);
}
STEP
(
"moving the content to a message produces the same message again"
)
{
auto
msg
=
builder
.
move_to_message
();
CAF_CHECK_EQUAL
(
msg
.
types
(),
(
make_type_id_list
<
int32_t
,
int32_t
,
int32_t
>
()));
CAF_CHECK_EQUAL
(
to_string
(
msg
.
types
()),
"[int32_t, int32_t, int32_t]"
);
CAF_CHECK_EQUAL
(
to_string
(
msg
),
"(1, 2, 3)"
);
}
}
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