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
646df4bf
Commit
646df4bf
authored
Nov 07, 2018
by
Dominik Charousset
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add copy-on-write tuple implementation
parent
84607e71
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
279 additions
and
0 deletions
+279
-0
libcaf_core/caf/cow_tuple.hpp
libcaf_core/caf/cow_tuple.hpp
+132
-0
libcaf_core/test/cow_tuple.cpp
libcaf_core/test/cow_tuple.cpp
+120
-0
libcaf_test/caf/test/dsl.hpp
libcaf_test/caf/test/dsl.hpp
+27
-0
No files found.
libcaf_core/caf/cow_tuple.hpp
0 → 100644
View file @
646df4bf
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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. *
******************************************************************************/
#pragma once
#include <tuple>
#include "caf/detail/apply_args.hpp"
#include "caf/detail/comparable.hpp"
#include "caf/detail/message_data.hpp"
#include "caf/detail/tuple_vals.hpp"
#include "caf/make_copy_on_write.hpp"
namespace
caf
{
/// A copy-on-write tuple implementation.
template
<
class
...
Ts
>
class
cow_tuple
:
detail
::
comparable
<
cow_tuple
<
Ts
...
>>
,
detail
::
comparable
<
cow_tuple
<
Ts
...
>
,
std
::
tuple
<
Ts
...
>>
{
public:
// -- member types -----------------------------------------------------------
using
impl
=
detail
::
tuple_vals
<
Ts
...
>
;
using
data_type
=
std
::
tuple
<
Ts
...
>
;
// -- constructors, destructors, and assignment operators --------------------
explicit
cow_tuple
(
Ts
...
xs
)
:
ptr_
(
make_copy_on_write
<
impl
>
(
std
::
move
(
xs
)...))
{
// nop
}
cow_tuple
()
:
ptr_
(
make_copy_on_write
<
impl
>
())
{
// nop
}
cow_tuple
(
cow_tuple
&&
)
=
default
;
cow_tuple
(
const
cow_tuple
&
)
=
default
;
cow_tuple
&
operator
=
(
cow_tuple
&&
)
=
default
;
cow_tuple
&
operator
=
(
const
cow_tuple
&
)
=
default
;
// -- properties -------------------------------------------------------------
/// Returns the managed tuple.
const
data_type
&
data
()
const
noexcept
{
return
ptr_
->
data
();
}
/// Returns a mutable reference to the managed tuple, guaranteed to have a
/// reference count of 1.
data_type
&
unshared
()
{
return
ptr_
.
unshared
().
data
();
}
/// Returns whether the reference count of the managed object is 1.
bool
unique
()
const
noexcept
{
return
ptr_
->
unique
();
}
/// @private
const
intrusive_cow_ptr
<
impl
>&
ptr
()
const
noexcept
{
return
ptr_
;
}
// -- comparison -------------------------------------------------------------
template
<
class
...
Us
>
int
compare
(
const
std
::
tuple
<
Us
...
>&
other
)
const
noexcept
{
return
data
()
<
other
?
-
1
:
(
data
()
==
other
?
0
:
1
);
}
template
<
class
...
Us
>
int
compare
(
const
cow_tuple
<
Us
...
>&
other
)
const
noexcept
{
return
compare
(
other
.
data
());
}
private:
// -- member variables -------------------------------------------------------
intrusive_cow_ptr
<
impl
>
ptr_
;
};
/// @relates cow_tuple
template
<
class
Inspector
,
class
...
Ts
>
typename
std
::
enable_if
<
Inspector
::
reads_state
,
typename
Inspector
::
result_type
>::
type
inspect
(
Inspector
&
f
,
const
cow_tuple
<
Ts
...
>&
x
)
{
return
f
(
x
.
data
());
}
/// @relates cow_tuple
template
<
class
Inspector
,
class
...
Ts
>
typename
std
::
enable_if
<
Inspector
::
writes_state
,
typename
Inspector
::
result_type
>::
type
inspect
(
Inspector
&
f
,
cow_tuple
<
Ts
...
>&
x
)
{
return
f
(
x
.
unshared
());
}
/// Creates a new copy-on-write tuple from given arguments.
/// @relates cow_tuple
template
<
class
...
Ts
>
cow_tuple
<
typename
std
::
decay
<
Ts
>::
type
...
>
make_cow_tuple
(
Ts
&&
...
xs
)
{
return
cow_tuple
<
typename
std
::
decay
<
Ts
>::
type
...
>
{
std
::
forward
<
Ts
>
(
xs
)...};
}
/// Convenience function for calling `get<N>(xs.data())`.
/// @relates cow_tuple
template
<
size_t
N
,
class
...
Ts
>
auto
get
(
const
cow_tuple
<
Ts
...
>&
xs
)
->
decltype
(
std
::
get
<
N
>
(
xs
.
data
()))
{
return
std
::
get
<
N
>
(
xs
.
data
());
}
}
// namespace caf
libcaf_core/test/cow_tuple.cpp
0 → 100644
View file @
646df4bf
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 cow_tuple
#include "caf/cow_tuple.hpp"
#include "caf/test/dsl.hpp"
using
std
::
make_tuple
;
using
std
::
string
;
using
std
::
tuple
;
using
namespace
caf
;
CAF_TEST
(
default_construction
)
{
cow_tuple
<
string
,
string
>
x
;
CAF_CHECK_EQUAL
(
x
.
unique
(),
true
);
CAF_CHECK_EQUAL
(
get
<
0
>
(
x
),
""
);
CAF_CHECK_EQUAL
(
get
<
1
>
(
x
),
""
);
}
CAF_TEST
(
value_construction
)
{
cow_tuple
<
int
,
int
>
x
{
1
,
2
};
CAF_CHECK_EQUAL
(
x
.
unique
(),
true
);
CAF_CHECK_EQUAL
(
get
<
0
>
(
x
),
1
);
CAF_CHECK_EQUAL
(
get
<
1
>
(
x
),
2
);
CAF_CHECK_EQUAL
(
x
,
make_cow_tuple
(
1
,
2
));
}
CAF_TEST
(
copy_construction
)
{
cow_tuple
<
int
,
int
>
x
{
1
,
2
};
cow_tuple
<
int
,
int
>
y
{
x
};
CAF_CHECK_EQUAL
(
x
,
y
);
CAF_CHECK_EQUAL
(
x
.
ptr
(),
y
.
ptr
());
CAF_CHECK_EQUAL
(
x
.
unique
(),
false
);
CAF_CHECK_EQUAL
(
y
.
unique
(),
false
);
}
CAF_TEST
(
move_construction
)
{
cow_tuple
<
int
,
int
>
x
{
1
,
2
};
cow_tuple
<
int
,
int
>
y
{
std
::
move
(
x
)};
CAF_CHECK_EQUAL
(
x
.
ptr
(),
nullptr
);
CAF_CHECK_EQUAL
(
y
,
make_tuple
(
1
,
2
));
CAF_CHECK_EQUAL
(
y
.
unique
(),
true
);
}
CAF_TEST
(
copy_assignment
)
{
cow_tuple
<
int
,
int
>
x
{
1
,
2
};
cow_tuple
<
int
,
int
>
y
{
3
,
4
};
CAF_CHECK_NOT_EQUAL
(
x
,
y
);
x
=
y
;
CAF_CHECK_EQUAL
(
x
,
y
);
CAF_CHECK_EQUAL
(
x
.
ptr
(),
y
.
ptr
());
CAF_CHECK_EQUAL
(
x
.
unique
(),
false
);
CAF_CHECK_EQUAL
(
y
.
unique
(),
false
);
}
CAF_TEST
(
move_assignment
)
{
cow_tuple
<
int
,
int
>
x
{
1
,
2
};
cow_tuple
<
int
,
int
>
y
{
3
,
4
};
CAF_CHECK_NOT_EQUAL
(
x
,
y
);
x
=
std
::
move
(
y
);
CAF_CHECK_EQUAL
(
x
,
make_tuple
(
3
,
4
));
CAF_CHECK_EQUAL
(
x
.
unique
(),
true
);
CAF_CHECK_EQUAL
(
y
.
ptr
(),
nullptr
);
}
CAF_TEST
(
make_cow_tuple
)
{
cow_tuple
<
int
,
int
>
x
{
1
,
2
};
auto
y
=
make_cow_tuple
(
1
,
2
);
CAF_CHECK_EQUAL
(
x
,
y
);
CAF_CHECK_EQUAL
(
x
.
unique
(),
true
);
CAF_CHECK_EQUAL
(
y
.
unique
(),
true
);
}
CAF_TEST
(
unsharing
)
{
auto
x
=
make_cow_tuple
(
string
{
"old"
},
string
{
"school"
});
auto
y
=
x
;
CAF_CHECK_EQUAL
(
x
.
unique
(),
false
);
CAF_CHECK_EQUAL
(
y
.
unique
(),
false
);
get
<
0
>
(
y
.
unshared
())
=
"new"
;
CAF_CHECK_EQUAL
(
x
.
unique
(),
true
);
CAF_CHECK_EQUAL
(
y
.
unique
(),
true
);
CAF_CHECK_EQUAL
(
x
.
data
(),
make_tuple
(
"old"
,
"school"
));
CAF_CHECK_EQUAL
(
y
.
data
(),
make_tuple
(
"new"
,
"school"
));
}
CAF_TEST
(
to_string
)
{
auto
x
=
make_cow_tuple
(
1
,
string
{
"abc"
});
CAF_CHECK_EQUAL
(
deep_to_string
(
x
),
"(1,
\"
abc
\"
)"
);
}
CAF_TEST_FIXTURE_SCOPE
(
cow_tuple_tests
,
test_coordinator_fixture
<>
)
CAF_TEST
(
serialization
)
{
auto
x
=
make_cow_tuple
(
1
,
2
,
3
);
auto
y
=
roundtrip
(
x
);
CAF_CHECK_EQUAL
(
x
,
y
);
CAF_CHECK_EQUAL
(
x
.
unique
(),
true
);
CAF_CHECK_EQUAL
(
y
.
unique
(),
true
);
CAF_CHECK_NOT_EQUAL
(
x
.
ptr
(),
y
.
ptr
());
}
CAF_TEST_FIXTURE_SCOPE_END
()
libcaf_test/caf/test/dsl.hpp
View file @
646df4bf
...
@@ -551,6 +551,9 @@ public:
...
@@ -551,6 +551,9 @@ public:
/// A deterministic scheduler type.
/// A deterministic scheduler type.
using
scheduler_type
=
caf
::
scheduler
::
test_coordinator
;
using
scheduler_type
=
caf
::
scheduler
::
test_coordinator
;
/// A buffer for serializing or deserializing objects.
using
byte_buffer
=
std
::
vector
<
char
>
;
// -- constructors, destructors, and assignment operators --------------------
// -- constructors, destructors, and assignment operators --------------------
template
<
class
...
Ts
>
template
<
class
...
Ts
>
...
@@ -702,6 +705,30 @@ public:
...
@@ -702,6 +705,30 @@ public:
return
dynamic_cast
<
T
&>
(
*
ptr
);
return
dynamic_cast
<
T
&>
(
*
ptr
);
}
}
template
<
class
...
Ts
>
byte_buffer
serialize
(
const
Ts
&
...
xs
)
{
byte_buffer
buf
;
caf
::
binary_serializer
sink
{
sys
,
buf
};
if
(
auto
err
=
sink
(
xs
...))
CAF_FAIL
(
"serialization failed: "
<<
sys
.
render
(
err
));
return
buf
;
}
template
<
class
...
Ts
>
void
deserialize
(
const
byte_buffer
&
buf
,
Ts
&
...
xs
)
{
caf
::
binary_deserializer
source
{
sys
,
buf
};
if
(
auto
err
=
source
(
xs
...))
CAF_FAIL
(
"deserialization failed: "
<<
sys
.
render
(
err
));
return
buf
;
}
template
<
class
T
>
T
roundtrip
(
const
T
&
x
)
{
T
result
;
deserialize
(
serialize
(
x
),
result
);
return
result
;
}
// -- member variables -------------------------------------------------------
// -- member variables -------------------------------------------------------
/// The user-generated system config.
/// The user-generated system config.
...
...
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