Commit 4f825ac0 authored by Dominik Charousset's avatar Dominik Charousset

Add first draft of caf::bb::container_source

parent 430bedea
cmake_minimum_required(VERSION 2.8.12)
project(caf_bb C CXX)
# get header files; only needed by CMake generators,
# e.g., for creating proper Xcode projects
file(GLOB_RECURSE LIBCAF_BB_HDRS "caf/*.hpp")
# --> Uncomment this block when adding the first .cpp file
#
# # list cpp files excluding platform-dependent files
# set(LIBCAF_BB_SRCS
# )
#
# add_custom_target(libcaf_bb)
#
# # build shared library if not compiling static only
# if (NOT CAF_BUILD_STATIC_ONLY)
# add_library(libcaf_bb_shared SHARED ${LIBCAF_BB_SRCS} ${LIBCAF_BB_HDRS})
# target_link_libraries(libcaf_bb_shared ${CAF_EXTRA_LDFLAGS})
# target_include_directories(libcaf_bb_shared PUBLIC
# $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
# $<INSTALL_INTERFACE:include>
# )
# set_target_properties(libcaf_bb_shared
# PROPERTIES
# SOVERSION ${CAF_VERSION}
# VERSION ${CAF_VERSION}
# OUTPUT_NAME caf_bb
# )
# install(TARGETS libcaf_bb_shared
# RUNTIME DESTINATION bin
# LIBRARY DESTINATION lib
# )
# add_dependencies(libcaf_bb_shared libcaf_bb)
# endif ()
#
# # build static library only if --build-static or --build-static-only was set
# if (CAF_BUILD_STATIC_ONLY OR CAF_BUILD_STATIC)
# add_library(libcaf_bb_static STATIC ${LIBCAF_BB_HDRS} ${LIBCAF_BB_SRCS})
# target_link_libraries(libcaf_bb_static ${CAF_EXTRA_LDFLAGS})
# target_include_directories(libcaf_bb_static PUBLIC
# $<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
# $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
# $<INSTALL_INTERFACE:include>
# )
# set_target_properties(libcaf_bb_static PROPERTIES OUTPUT_NAME caf_bb_static)
# install(TARGETS libcaf_bb_static ARCHIVE DESTINATION lib)
# add_dependencies(libcaf_bb_static libcaf_bb)
# endif ()
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/caf"
DESTINATION include
FILES_MATCHING PATTERN "*.hpp")
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 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 <iterator>
#include "caf/behavior.hpp"
#include "caf/event_based_actor.hpp"
#include "caf/stateful_actor.hpp"
#include "caf/unit.hpp"
namespace caf {
namespace bb {
/// @relates container_source
template <class Container>
struct container_source_state {
// -- constructors, destructors, and assignment operators --------------------
container_source_state() : name("container-source"), i(xs.end()) {
// nop
}
void init(Container&& elements) {
xs = std::move(elements);
i = xs.begin();
}
// -- properties -------------------------------------------------------------
size_t remaining() const {
return static_cast<size_t>(std::distance(i, xs.end()));
}
size_t at_end() const {
return i == xs.end();
}
// -- member variables -------------------------------------------------------
/// Gives this actor a useful name in CAF logs.
const char* name;
/// Caches the elements we are about to stream.
Container xs;
/// Points at the current streaming position.
typename Container::iterator i;
};
/// @relates container_source
template <class Container>
using container_source_type = stateful_actor<container_source_state<Container>>;
/// Streams the content of given container `xs` to all given stream sinks.
template <class Container, class Handle, class... Handles>
behavior container_source(container_source_type<Container>* self, Container xs,
Handle sink, Handles... sinks) {
using value_type = typename Container::value_type;
// Fail early if we got nothing to stream.
if (xs.empty())
return {};
// Spin up stream manager and connect the first sink.
self->state.init(std::move(xs));
auto src = self->make_source(
std::move(sink),
[&](unit_t&) {
// nop
},
[self](unit_t&, downstream<value_type>& out, size_t hint) {
auto& st = self->state;
auto n = std::min(hint, st.remaining());
for (size_t pushed = 0; pushed < n; ++pushed)
out.push(std::move(*st.i++));
},
[self](const unit_t&) { return self->state.at_end(); });
// Add the remaining sinks.
std::initializer_list<unit_t>{src.ptr()->add_outbound_path(sinks)...};
return {};
};
/// Convenience function for spawning container sources.
} // namespace bb
} // namespace caf
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright 2011-2019 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 container_source
#include "caf/bb/container_source.hpp"
#include "caf/test/dsl.hpp"
#include <vector>
using namespace caf;
namespace {
struct fixture {
};
} // namespace <anonymous>
CAF_TEST_FIXTURE_SCOPE(container_source_tests, fixture)
CAF_TEST(todo) {
// implement me
}
CAF_TEST_FIXTURE_SCOPE_END()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment