Commit 9bea72e9 authored by Dominik Charousset's avatar Dominik Charousset

correctly forward additional args for IO actors

parent 1fcfec71
......@@ -32,6 +32,7 @@ cppa/detail/disablable_delete.hpp
cppa/detail/empty_tuple.hpp
cppa/detail/event_based_actor_factory.hpp
cppa/detail/fd_util.hpp
cppa/detail/fwd.hpp
cppa/detail/get_behavior.hpp
cppa/detail/group_manager.hpp
cppa/detail/implicit_conversions.hpp
......
......@@ -629,7 +629,7 @@ actor_ptr spawn_io(network::input_stream_ptr in,
auto backend = make_counted<io_actor_backend>(std::move(in), std::move(out), ptr);
backend->init();
mm->run_later([=] { mm->continue_reader(backend); });
return eval_sopts(Options, ptr);
return eval_sopts(Options, std::move(ptr));
}
/**
......@@ -638,18 +638,20 @@ actor_ptr spawn_io(network::input_stream_ptr in,
* @tparam Options Optional flags to modify <tt>spawn</tt>'s behavior.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
template<spawn_options Options = no_spawn_options, typename... Ts>
actor_ptr spawn_io(std::function<void (network::io_service*)> fun,
template<spawn_options Options = no_spawn_options,
typename F = std::function<void (network::io_service*)>,
typename... Ts>
actor_ptr spawn_io(F fun,
network::input_stream_ptr in,
network::output_stream_ptr out,
Ts&&... args) {
using namespace network;
auto mm = get_middleman();
auto ptr = io_actor::from(std::move(fun));
auto ptr = io_actor::from(std::move(fun), std::forward<Ts>(args)...);
auto backend = make_counted<io_actor_backend>(std::move(in), std::move(out), ptr);
backend->init();
mm->run_later([=] { mm->continue_reader(backend); });
return eval_sopts(Options, ptr);
return eval_sopts(Options, std::move(ptr));
}
/**
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef FWD_HPP
#define FWD_HPP
#include "cppa/self.hpp"
namespace cppa { namespace detail {
template<typename T>
struct is_self {
typedef typename util::rm_const_and_ref<T>::type plain_type;
static constexpr bool value = std::is_same<plain_type, self_type>::value;
};
template<typename T, typename U>
auto fwd(U& arg, typename std::enable_if<!is_self<T>::value>::type* = 0)
-> decltype(std::forward<T>(arg)) {
return std::forward<T>(arg);
}
template<typename T, typename U>
local_actor* fwd(U& arg, typename std::enable_if<is_self<T>::value>::type* = 0){
return arg;
}
} } // namespace cppa::detail
#endif // FWD_HPP
......@@ -31,6 +31,8 @@
#ifndef IO_ACTOR_HPP
#define IO_ACTOR_HPP
#include <functional>
#include "cppa/stackless.hpp"
#include "cppa/threadless.hpp"
#include "cppa/local_actor.hpp"
......@@ -38,6 +40,8 @@
#include "cppa/network/io_service.hpp"
#include "cppa/detail/fwd.hpp"
namespace cppa { namespace network {
class io_actor_backend;
......@@ -60,6 +64,14 @@ class io_actor : public extend<local_actor>::with<threadless, stackless> {
static intrusive_ptr<io_actor> from(std::function<void (io_service*)> fun);
template<typename F, typename T0, typename... Ts>
static intrusive_ptr<io_actor> from(F fun, T0&& arg0, Ts&&... args) {
return from(std::bind(std::move(fun),
std::placeholders::_1,
detail::fwd<T0>(arg0),
detail::fwd<Ts>(args)...));
}
protected:
io_service& io_handle();
......
......@@ -48,29 +48,14 @@
#include "cppa/util/duration.hpp"
#include "cppa/detail/fwd.hpp"
namespace cppa {
class self_type;
class scheduler_helper;
namespace detail { class singleton_manager; } // namespace detail
namespace detail {
template<typename T>
struct is_self {
typedef typename util::rm_const_and_ref<T>::type plain_type;
static constexpr bool value = std::is_same<plain_type, self_type>::value;
};
template<typename T, typename U>
auto fwd(U& arg, typename std::enable_if<!is_self<T>::value>::type* = 0)
-> decltype(std::forward<T>(arg)) {
return std::forward<T>(arg);
}
template<typename T, typename U>
local_actor* fwd(U& arg, typename std::enable_if<is_self<T>::value>::type* = 0){
return arg;
}
} // namespace detail
/**
* @brief This abstract class allows to create (spawn) new actors
* and offers delayed sends.
......
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