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
2a83ea58
Unverified
Commit
2a83ea58
authored
Nov 13, 2018
by
Joseph Noir
Committed by
GitHub
Nov 13, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #791
Add copy-on-write tuple implementation
parents
9cdc4b4b
e71d8bce
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
276 additions
and
0 deletions
+276
-0
libcaf_core/caf/cow_tuple.hpp
libcaf_core/caf/cow_tuple.hpp
+130
-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
+26
-0
No files found.
libcaf_core/caf/cow_tuple.hpp
0 → 100644
View file @
2a83ea58
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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/comparable.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 @
2a83ea58
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| 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 @
2a83ea58
...
@@ -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,29 @@ public:
...
@@ -702,6 +705,29 @@ 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
));
}
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