mirror of
https://github.com/Naios/continuable.git
synced 2025-12-07 17:26:47 +08:00
Add cti::populate and make use of it in tests
This commit is contained in:
parent
86c3815ae0
commit
de40af0927
@ -31,7 +31,10 @@
|
|||||||
#ifndef CONTINUABLE_COMPOSITIONS_HPP_INCLUDED
|
#ifndef CONTINUABLE_COMPOSITIONS_HPP_INCLUDED
|
||||||
#define CONTINUABLE_COMPOSITIONS_HPP_INCLUDED
|
#define CONTINUABLE_COMPOSITIONS_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <memory>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <continuable/detail/composition-all.hpp>
|
#include <continuable/detail/composition-all.hpp>
|
||||||
#include <continuable/detail/composition-any.hpp>
|
#include <continuable/detail/composition-any.hpp>
|
||||||
@ -242,6 +245,49 @@ template <
|
|||||||
auto when_any(Iterator begin, Iterator end) {
|
auto when_any(Iterator begin, Iterator end) {
|
||||||
return when_any(detail::range::persist_range(begin, end));
|
return when_any(detail::range::persist_range(begin, end));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Populates a homogeneous container from the given arguments.
|
||||||
|
/// All arguments need to be convertible to the first one,
|
||||||
|
/// by default std::vector is used as container type.
|
||||||
|
///
|
||||||
|
/// This method mainly helps to create a homogeneous container from
|
||||||
|
/// a runtime known count of continuables which type isn't exactly known.
|
||||||
|
/// All continuables which are passed to this function should be originating
|
||||||
|
/// from the same source or a method called with the same types of arguments:
|
||||||
|
/// ```cpp
|
||||||
|
/// auto container = cti::populate(cti::make_ready_continuable(0),
|
||||||
|
/// cti::make_ready_continuable(1)),
|
||||||
|
///
|
||||||
|
/// for (int i = 2; i < 5; ++i) {
|
||||||
|
/// // You may add more continuables to the container afterwards
|
||||||
|
/// container.emplace_back(cti::make_ready_continuable(i));
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// cti::when_any(std::move(container))
|
||||||
|
/// .then([](int) {
|
||||||
|
/// // ...
|
||||||
|
/// });
|
||||||
|
/// ```
|
||||||
|
/// Additionally it is possible to change the targeted container as below:
|
||||||
|
/// ```cpp
|
||||||
|
/// auto container = cti::populate<std::list>(cti::make_ready_continuable(0),
|
||||||
|
/// cti::make_ready_continuable(1)),
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// \tparam C The container type which is used to store the arguments into.
|
||||||
|
///
|
||||||
|
/// \since 3.0.0
|
||||||
|
template <template <typename, typename> class C = std::vector, typename First,
|
||||||
|
typename... Args>
|
||||||
|
C<std::decay_t<First>, std::allocator<std::decay_t<First>>>
|
||||||
|
populate(First&& first, Args&&... args) {
|
||||||
|
C<std::decay_t<First>, std::allocator<std::decay_t<First>>> container;
|
||||||
|
container.reserve(1 + sizeof...(Args));
|
||||||
|
container.emplace_back(std::forward<First>(first));
|
||||||
|
(void)std::initializer_list<int>{
|
||||||
|
0, ((void)container.emplace_back(std::forward<Args>(args)), 0)...};
|
||||||
|
return container; // RVO
|
||||||
|
}
|
||||||
} // namespace cti
|
} // namespace cti
|
||||||
|
|
||||||
#endif // CONTINUABLE_COMPOSITIONS_HPP_INCLUDED
|
#endif // CONTINUABLE_COMPOSITIONS_HPP_INCLUDED
|
||||||
|
|||||||
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <continuable/detail/traits.hpp>
|
#include <continuable/detail/traits.hpp>
|
||||||
@ -52,11 +53,11 @@ struct is_iterator<T,
|
|||||||
template <typename Iterator>
|
template <typename Iterator>
|
||||||
auto persist_range(Iterator begin, Iterator end) {
|
auto persist_range(Iterator begin, Iterator end) {
|
||||||
std::vector<typename std::iterator_traits<Iterator>::value_type> storage;
|
std::vector<typename std::iterator_traits<Iterator>::value_type> storage;
|
||||||
|
// TODO Find out why the superior idiom below has issues with move only types:
|
||||||
storage.insert(storage.end(), std::make_move_iterator(begin),
|
// storage.insert(storage.end(), std::make_move_iterator(begin),
|
||||||
std::make_move_iterator(end));
|
// std::make_move_iterator(end));
|
||||||
|
std::move(begin, end, std::back_inserter(storage));
|
||||||
return storage; // RVO
|
return storage;
|
||||||
}
|
}
|
||||||
} // namespace range
|
} // namespace range
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|||||||
@ -126,19 +126,21 @@ void old() {
|
|||||||
int main(int, char**) {
|
int main(int, char**) {
|
||||||
using namespace cti::detail;
|
using namespace cti::detail;
|
||||||
|
|
||||||
cti::when_seq(
|
{
|
||||||
cti::make_ready_continuable(0, 1), 2, //< See this plain value
|
cti::when_seq(
|
||||||
std::vector<cti::continuable<int>>{cti::make_ready_continuable(3),
|
cti::make_ready_continuable(0, 1), 2, //< See this plain value
|
||||||
cti::make_ready_continuable(4)},
|
cti::populate(cti::make_ready_continuable(3),
|
||||||
std::make_tuple(std::make_tuple(cti::make_ready_continuable(5))))
|
cti::make_ready_continuable(4)),
|
||||||
.then([](int r0, int r1, int r2, std::vector<int> r34,
|
std::make_tuple(std::make_tuple(cti::make_ready_continuable(5))))
|
||||||
std::tuple<std::tuple<int>> r5) {
|
.then([](int r0, int r1, int r2, std::vector<int> r34,
|
||||||
// ...
|
std::tuple<std::tuple<int>> r5) {
|
||||||
util::unused(r0, r1, r2, r34, r5);
|
// ...
|
||||||
});
|
util::unused(r0, r1, r2, r34, r5);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<cti::continuable<int>> v{cti::make_ready_continuable(8),
|
auto v = cti::populate(cti::make_ready_continuable(8),
|
||||||
cti::make_ready_continuable(9)};
|
cti::make_ready_continuable(9));
|
||||||
|
|
||||||
cti::when_seq(v.begin(), v.end()).then([](auto o2) {
|
cti::when_seq(v.begin(), v.end()).then([](auto o2) {
|
||||||
// ...
|
// ...
|
||||||
@ -162,8 +164,8 @@ int main(int, char**) {
|
|||||||
|
|
||||||
cti::when_all(
|
cti::when_all(
|
||||||
cti::make_ready_continuable(0, 1), 2, //< See this plain value
|
cti::make_ready_continuable(0, 1), 2, //< See this plain value
|
||||||
std::vector<cti::continuable<int>>{cti::make_ready_continuable(3),
|
cti::populate(cti::make_ready_continuable(3),
|
||||||
cti::make_ready_continuable(4)},
|
cti::make_ready_continuable(4)),
|
||||||
std::make_tuple(std::make_tuple(cti::make_ready_continuable(5))))
|
std::make_tuple(std::make_tuple(cti::make_ready_continuable(5))))
|
||||||
.then([](int r0, int r1, int r2, std::vector<int> r34,
|
.then([](int r0, int r1, int r2, std::vector<int> r34,
|
||||||
std::tuple<std::tuple<int>> r5) {
|
std::tuple<std::tuple<int>> r5) {
|
||||||
|
|||||||
@ -75,15 +75,8 @@ void test_all_seq_aggregate(Supplier&& supply, AggregateConnector&& ag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
using type_t = std::decay_t<decltype(
|
auto chain = ag(std::make_tuple(
|
||||||
std::declval<Supplier>()(std::declval<int>(), std::declval<int>()))>;
|
cti::populate(supply(1, 2), supply(3, 4), supply(5, 6))));
|
||||||
|
|
||||||
std::vector<type_t> v;
|
|
||||||
v.push_back(supply(1, 2));
|
|
||||||
v.push_back(supply(3, 4));
|
|
||||||
v.push_back(supply(5, 6));
|
|
||||||
|
|
||||||
auto chain = ag(std::make_tuple(std::move(v)));
|
|
||||||
EXPECT_ASYNC_RESULT(std::move(chain),
|
EXPECT_ASYNC_RESULT(std::move(chain),
|
||||||
std::make_tuple(std::vector<std::tuple<int, int>>{
|
std::make_tuple(std::vector<std::tuple<int, int>>{
|
||||||
{1, 2}, {3, 4}, {5, 6}}));
|
{1, 2}, {3, 4}, {5, 6}}));
|
||||||
|
|||||||
@ -68,15 +68,8 @@ TYPED_TEST(single_dimension_tests, is_logical_any_connectable) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
using type_t = std::decay_t<decltype(std::declval<TestFixture>().supply(
|
auto chain = cti::when_any(std::make_tuple(std::move(cti::populate(
|
||||||
std::declval<int>(), std::declval<int>()))>;
|
this->supply(1, 2), this->supply(3, 4), this->supply(5, 6)))));
|
||||||
|
|
||||||
std::vector<type_t> v;
|
|
||||||
v.push_back(this->supply(1, 2));
|
|
||||||
v.push_back(this->supply(3, 4));
|
|
||||||
v.push_back(this->supply(5, 6));
|
|
||||||
|
|
||||||
auto chain = cti::when_any(std::make_tuple(std::move(v)));
|
|
||||||
EXPECT_ASYNC_RESULT(std::move(chain), 1, 2);
|
EXPECT_ASYNC_RESULT(std::move(chain), 1, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user