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
e3e1404c
Commit
e3e1404c
authored
Jan 20, 2020
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add scaffold for new type_id API
parent
13fc58a2
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
730 additions
and
3 deletions
+730
-3
.clang-format
.clang-format
+2
-2
libcaf_core/CMakeLists.txt
libcaf_core/CMakeLists.txt
+2
-0
libcaf_core/caf/detail/make_meta_object.hpp
libcaf_core/caf/detail/make_meta_object.hpp
+62
-0
libcaf_core/caf/detail/meta_object.hpp
libcaf_core/caf/detail/meta_object.hpp
+71
-0
libcaf_core/caf/fwd.hpp
libcaf_core/caf/fwd.hpp
+7
-1
libcaf_core/caf/init_global_meta_objects.hpp
libcaf_core/caf/init_global_meta_objects.hpp
+75
-0
libcaf_core/caf/type_id.hpp
libcaf_core/caf/type_id.hpp
+256
-0
libcaf_core/src/detail/meta_object.cpp
libcaf_core/src/detail/meta_object.cpp
+78
-0
libcaf_core/test/detail/meta_object.cpp
libcaf_core/test/detail/meta_object.cpp
+177
-0
No files found.
.clang-format
View file @
e3e1404c
...
...
@@ -32,8 +32,8 @@ IndentWidth: 2
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
Language: Cpp
MacroBlockBegin: "^BEGIN_STATE$"
MacroBlockEnd: "^END_STATE$"
MacroBlockBegin: "^BEGIN_STATE$
|CAF_BEGIN_TYPE_ID_BLOCK
"
MacroBlockEnd: "^END_STATE$
|CAF_END_TYPE_ID_BLOCK
"
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
PenaltyBreakAssignment: 25
...
...
libcaf_core/CMakeLists.txt
View file @
e3e1404c
...
...
@@ -69,6 +69,7 @@ set(CAF_CORE_SOURCES
src/detail/ini_consumer.cpp
src/detail/invoke_result_visitor.cpp
src/detail/message_data.cpp
src/detail/meta_object.cpp
src/detail/parse.cpp
src/detail/parser/chars.cpp
src/detail/pretty_type_name.cpp
...
...
@@ -193,6 +194,7 @@ set(CAF_CORE_TEST_SOURCES
test/detail/bounds_checker.cpp
test/detail/ini_consumer.cpp
test/detail/limited_vector.cpp
test/detail/meta_object.cpp
test/detail/parse.cpp
test/detail/parser/read_bool.cpp
test/detail/parser/read_floating_point.cpp
...
...
libcaf_core/caf/detail/make_meta_object.hpp
0 → 100644
View file @
e3e1404c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 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. *
******************************************************************************/
#pragma once
#include <algorithm>
#include <cstddef>
#include "caf/binary_deserializer.hpp"
#include "caf/binary_serializer.hpp"
#include "caf/byte.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/meta_object.hpp"
#include "caf/error.hpp"
#include "caf/serializer.hpp"
namespace
caf
::
detail
{
template
<
class
T
>
meta_object
make_meta_object
(
const
char
*
type_name
)
{
return
{
type_name
,
[](
void
*
ptr
)
noexcept
{
reinterpret_cast
<
T
*>
(
ptr
)
->~
T
();
},
[](
void
*
ptr
)
{
new
(
ptr
)
T
();
},
[](
caf
::
binary_serializer
&
sink
,
const
void
*
ptr
)
{
return
sink
(
*
reinterpret_cast
<
const
T
*>
(
ptr
));
},
[](
caf
::
binary_deserializer
&
source
,
void
*
ptr
)
{
return
source
(
*
reinterpret_cast
<
T
*>
(
ptr
));
},
[](
caf
::
serializer
&
sink
,
const
void
*
ptr
)
{
return
sink
(
*
reinterpret_cast
<
const
T
*>
(
ptr
));
},
[](
caf
::
deserializer
&
source
,
void
*
ptr
)
{
return
source
(
*
reinterpret_cast
<
T
*>
(
ptr
));
},
};
}
template
<
class
...
Ts
>
void
register_meta_objects
(
size_t
first_id
)
{
auto
xs
=
resize_global_meta_objects
(
first_id
+
sizeof
...(
Ts
));
meta_object
src
[]
=
{
make_meta_object
<
Ts
>
()...};
std
::
copy
(
src
,
src
+
sizeof
...(
Ts
),
xs
.
begin
()
+
first_id
);
}
}
// namespace caf::detail
libcaf_core/caf/detail/meta_object.hpp
0 → 100644
View file @
e3e1404c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 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. *
******************************************************************************/
#pragma once
#include <cstddef>
#include <cstdint>
#include "caf/detail/core_export.hpp"
#include "caf/fwd.hpp"
namespace
caf
::
detail
{
/// Enables destroying, construcing and serializing objects through type-erased
/// pointers.
struct
meta_object
{
/// Stores a human-readable representation of the type's name.
const
char
*
type_name
;
/// Calls the destructor for given object.
void
(
*
destroy
)(
void
*
)
noexcept
;
/// Creates a new object at given memory location by calling the default
/// constructor.
void
(
*
default_construct
)(
void
*
);
/// Applies an object to a binary serializer.
error_code
<
sec
>
(
*
save_binary
)(
caf
::
binary_serializer
&
,
const
void
*
);
/// Applies an object to a binary deserializer.
error_code
<
sec
>
(
*
load_binary
)(
caf
::
binary_deserializer
&
,
void
*
);
/// Applies an object to a generic serializer.
caf
::
error
(
*
save
)(
caf
::
serializer
&
,
const
void
*
);
/// Applies an object to a generic deserializer.
caf
::
error
(
*
load
)(
caf
::
deserializer
&
,
void
*
);
};
/// Returns the global storage for all meta objects. The ::type_id of an object
/// is the index for accessing the corresonding meta object.
CAF_CORE_EXPORT
span
<
const
meta_object
>
global_meta_objects
();
/// Returns the global meta object for given type ID.
CAF_CORE_EXPORT
meta_object
&
global_meta_object
(
uint16_t
id
);
/// Clears the array for storing global meta objects. Meant for unit testing
/// only!
CAF_CORE_EXPORT
void
clear_global_meta_objects
();
/// Resizes and returns the global storage for all meta objects. Existing
/// entries are copied to the new memory region. The new size *must* grow the
/// array.
CAF_CORE_EXPORT
span
<
meta_object
>
resize_global_meta_objects
(
size_t
size
);
}
// namespace caf::detail
libcaf_core/caf/fwd.hpp
View file @
e3e1404c
...
...
@@ -40,13 +40,17 @@ template <class> class intrusive_ptr;
template
<
class
>
class
optional
;
template
<
class
>
class
param
;
template
<
class
>
class
span
;
template
<
class
>
class
stream
;
template
<
class
>
class
stream
;
;
template
<
class
>
class
stream_sink
;
template
<
class
>
class
stream_source
;
template
<
class
>
class
trivial_match_case
;
template
<
class
>
class
weak_intrusive_ptr
;
template
<
class
>
struct
timeout_definition
;
template
<
class
>
struct
type_id
;
template
<
uint16_t
>
struct
type_by_id
;
template
<
uint16_t
>
struct
type_name_by_id
;
// -- 2 param templates --------------------------------------------------------
...
...
@@ -272,6 +276,8 @@ class message_data;
class
private_thread
;
class
uri_impl
;
struct
meta_object
;
// enable intrusive_ptr<uri_impl> with forward declaration only
CAF_CORE_EXPORT
void
intrusive_ptr_add_ref
(
const
uri_impl
*
);
CAF_CORE_EXPORT
void
intrusive_ptr_release
(
const
uri_impl
*
);
...
...
libcaf_core/caf/init_global_meta_objects.hpp
0 → 100644
View file @
e3e1404c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 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. *
******************************************************************************/
#pragma once
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <utility>
#include "caf/detail/make_meta_object.hpp"
#include "caf/detail/meta_object.hpp"
#include "caf/type_id.hpp"
namespace
caf
::
detail
{
template
<
uint16_t
First
,
uint16_t
Second
>
struct
type_id_pair
{};
template
<
class
Range
,
uint16_t
...
Is
>
struct
type_id_sequence_helper
;
template
<
uint16_t
End
,
uint16_t
...
Is
>
struct
type_id_sequence_helper
<
type_id_pair
<
End
,
End
>
,
Is
...
>
{
using
type
=
std
::
integer_sequence
<
uint16_t
,
Is
...
>
;
};
template
<
uint16_t
Begin
,
uint16_t
End
,
uint16_t
...
Is
>
struct
type_id_sequence_helper
<
type_id_pair
<
Begin
,
End
>
,
Is
...
>
{
using
type
=
typename
type_id_sequence_helper
<
type_id_pair
<
Begin
+
1
,
End
>
,
Is
...,
Begin
>::
type
;
};
template
<
uint16_t
Begin
,
uint16_t
End
>
using
make_type_id_sequence
=
typename
type_id_sequence_helper
<
type_id_pair
<
Begin
,
End
>>::
type
;
}
// namespace caf::detail
namespace
caf
{
template
<
uint16_t
...
Is
>
void
init_global_meta_objects_impl
(
std
::
integer_sequence
<
uint16_t
,
Is
...
>
,
size_t
begin
,
size_t
end
)
{
detail
::
meta_object
src
[]
=
{
detail
::
make_meta_object
<
type_by_id_t
<
Is
>>
(
type_name_by_id_v
<
Is
>
)...,
};
auto
dst
=
detail
::
resize_global_meta_objects
(
end
);
std
::
copy
(
src
,
src
+
sizeof
...(
Is
),
dst
.
begin
()
+
begin
);
}
template
<
class
ProjectIds
>
void
init_global_meta_objects
()
{
static
constexpr
uint16_t
begin
=
ProjectIds
::
first
;
static
constexpr
uint16_t
end
=
ProjectIds
::
last
+
1
;
init_global_meta_objects_impl
(
detail
::
make_type_id_sequence
<
begin
,
end
>
{},
begin
,
end
);
}
}
// namespace caf
libcaf_core/caf/type_id.hpp
0 → 100644
View file @
e3e1404c
This diff is collapsed.
Click to expand it.
libcaf_core/src/detail/meta_object.cpp
0 → 100644
View file @
e3e1404c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 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. *
******************************************************************************/
#include "caf/detail/meta_object.hpp"
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include "caf/config.hpp"
#include "caf/span.hpp"
namespace
caf
::
detail
{
namespace
{
// Stores global type information.
meta_object
*
meta_objects
;
// Stores the size of `meta_objects`.
size_t
meta_objects_size
;
// Make sure to clean up all meta objects on program exit.
struct
meta_objects_cleanup
{
~
meta_objects_cleanup
()
{
delete
[]
meta_objects
;
}
}
cleanup_helper
;
}
// namespace
span
<
const
meta_object
>
global_meta_objects
()
{
return
{
meta_objects
,
meta_objects_size
};
}
meta_object
&
global_meta_object
(
uint16_t
id
)
{
CAF_ASSERT
(
id
<
meta_objects_size
);
return
meta_objects
[
id
];
}
void
clear_global_meta_objects
()
{
if
(
meta_objects
!=
nullptr
)
{
delete
meta_objects
;
meta_objects
=
nullptr
;
meta_objects_size
=
0
;
}
}
span
<
meta_object
>
resize_global_meta_objects
(
size_t
size
)
{
if
(
size
<=
meta_objects_size
)
{
fprintf
(
stderr
,
"resize_global_meta_objects called with a new size that "
"does not grow the array
\n
"
);
abort
();
}
auto
new_storage
=
new
meta_object
[
size
];
std
::
copy
(
meta_objects
,
meta_objects
+
meta_objects_size
,
new_storage
);
delete
[]
meta_objects
;
meta_objects
=
new_storage
;
meta_objects_size
=
size
;
return
{
new_storage
,
size
};
}
}
// namespace caf::detail
libcaf_core/test/detail/meta_object.cpp
0 → 100644
View file @
e3e1404c
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2020 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 detail.meta_object
#include "caf/detail/meta_object.hpp"
#include "caf/test/dsl.hpp"
#include <tuple>
#include <type_traits>
#include "caf/binary_deserializer.hpp"
#include "caf/binary_serializer.hpp"
#include "caf/detail/make_meta_object.hpp"
#include "caf/init_global_meta_objects.hpp"
using
namespace
std
::
string_literals
;
using
namespace
caf
;
using
namespace
caf
::
detail
;
namespace
{
struct
i32_wrapper
{
static
size_t
instances
;
int32_t
value
;
i32_wrapper
()
:
value
(
0
)
{
++
instances
;
}
~
i32_wrapper
()
{
--
instances
;
}
};
template
<
class
Inspector
>
auto
inspect
(
Inspector
&
f
,
i32_wrapper
&
x
)
{
return
f
(
x
.
value
);
}
size_t
i32_wrapper
::
instances
=
0
;
struct
i64_wrapper
{
static
size_t
instances
;
int64_t
value
;
i64_wrapper
()
:
value
(
0
)
{
++
instances
;
}
~
i64_wrapper
()
{
--
instances
;
}
};
template
<
class
Inspector
>
auto
inspect
(
Inspector
&
f
,
i64_wrapper
&
x
)
{
return
f
(
x
.
value
);
}
size_t
i64_wrapper
::
instances
=
0
;
}
// namespace
CAF_BEGIN_TYPE_ID_BLOCK
(
meta_object_suite
,
caf
::
first_custom_type_id
)
CAF_ADD_TYPE_ID
(
meta_object_suite
,
i32_wrapper
)
CAF_ADD_TYPE_ID
(
meta_object_suite
,
i64_wrapper
)
CAF_END_TYPE_ID_BLOCK
(
meta_object_suite
)
namespace
caf
{
static_assert
(
meta_object_suite_first_type_id
==
first_custom_type_id
);
static_assert
(
meta_object_suite_last_type_id
==
first_custom_type_id
+
1
);
static_assert
(
type_id
<
i32_wrapper
>::
value
==
first_custom_type_id
);
static_assert
(
type_id
<
i64_wrapper
>::
value
==
first_custom_type_id
+
1
);
static_assert
(
type_id
<
i32_wrapper
>::
value
==
meta_object_suite_first_type_id
);
static_assert
(
type_id
<
i64_wrapper
>::
value
==
meta_object_suite_last_type_id
);
}
// namespace caf
namespace
{
struct
fixture
{
fixture
()
{
CAF_ASSERT
(
i32_wrapper
::
instances
==
0
);
clear_global_meta_objects
();
}
};
}
// namespace
CAF_TEST_FIXTURE_SCOPE
(
meta_object_suite
,
fixture
)
CAF_TEST
(
meta
objects
allow
construction
and
destruction
of
objects
)
{
auto
meta_i32_wrapper
=
make_meta_object
<
i32_wrapper
>
(
"i32_wrapper"
);
std
::
aligned_storage_t
<
sizeof
(
i32_wrapper
),
alignof
(
i32_wrapper
)
>
storage
;
meta_i32_wrapper
.
default_construct
(
&
storage
);
CAF_CHECK_EQUAL
(
i32_wrapper
::
instances
,
1u
);
meta_i32_wrapper
.
destroy
(
&
storage
);
CAF_CHECK_EQUAL
(
i32_wrapper
::
instances
,
0u
);
}
CAF_TEST
(
meta
objects
allow
serialization
of
objects
)
{
byte_buffer
buf
;
auto
meta_i32_wrapper
=
make_meta_object
<
i32_wrapper
>
(
"i32_wrapper"
);
std
::
aligned_storage_t
<
sizeof
(
i32_wrapper
),
alignof
(
i32_wrapper
)
>
storage
;
binary_serializer
sink
{
nullptr
,
buf
};
meta_i32_wrapper
.
default_construct
(
&
storage
);
CAF_CHECK_EQUAL
(
i32_wrapper
::
instances
,
1u
);
meta_i32_wrapper
.
save_binary
(
sink
,
&
storage
);
i32_wrapper
copy
;
CAF_CHECK_EQUAL
(
i32_wrapper
::
instances
,
2u
);
copy
.
value
=
42
;
binary_deserializer
source
{
nullptr
,
buf
};
meta_i32_wrapper
.
load_binary
(
source
,
&
copy
);
CAF_CHECK_EQUAL
(
copy
.
value
,
0
);
meta_i32_wrapper
.
destroy
(
&
storage
);
CAF_CHECK_EQUAL
(
i32_wrapper
::
instances
,
1u
);
}
CAF_TEST
(
resizing
the
global
meta
objects
keeps
entries
)
{
auto
eq
=
[](
const
meta_object
&
x
,
const
meta_object
&
y
)
{
return
std
::
tie
(
x
.
destroy
,
x
.
default_construct
,
x
.
save_binary
,
x
.
load_binary
,
x
.
save
,
x
.
load
)
==
std
::
tie
(
y
.
destroy
,
y
.
default_construct
,
y
.
save_binary
,
y
.
load_binary
,
y
.
save
,
y
.
load
);
};
auto
meta_i32
=
make_meta_object
<
int32_t
>
(
"int32_t"
);
auto
xs1
=
resize_global_meta_objects
(
1
);
CAF_CHECK_EQUAL
(
xs1
.
size
(),
1u
);
xs1
[
0
]
=
meta_i32
;
CAF_CHECK
(
eq
(
xs1
[
0
],
meta_i32
));
auto
xs2
=
resize_global_meta_objects
(
2
);
CAF_CHECK_EQUAL
(
xs2
.
size
(),
2u
);
CAF_CHECK
(
eq
(
xs2
[
0
],
meta_i32
));
resize_global_meta_objects
(
3
);
CAF_CHECK
(
eq
(
global_meta_object
(
0
),
meta_i32
));
}
CAF_TEST
(
init_global_meta_objects
takes
care
of
creating
a
meta
object
table
)
{
init_global_meta_objects
<
meta_object_suite_type_ids
>
();
auto
xs
=
global_meta_objects
();
CAF_REQUIRE_EQUAL
(
xs
.
size
(),
meta_object_suite_last_type_id
+
1u
);
CAF_CHECK_EQUAL
(
type_name_by_id_v
<
type_id_v
<
i32_wrapper
>>
,
"i32_wrapper"
s
);
CAF_CHECK_EQUAL
(
type_name_by_id_v
<
type_id_v
<
i64_wrapper
>>
,
"i64_wrapper"
s
);
CAF_CHECK_EQUAL
(
xs
[
type_id_v
<
i32_wrapper
>
].
type_name
,
"i32_wrapper"
s
);
CAF_CHECK_EQUAL
(
xs
[
type_id_v
<
i64_wrapper
>
].
type_name
,
"i64_wrapper"
s
);
}
CAF_TEST_FIXTURE_SCOPE_END
()
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