mirror of
https://github.com/boostorg/process.git
synced 2026-01-25 06:22:14 +00:00
Merge pull request #29 from klemens-morgenstern/develop
Added rvalue qualification & documentation fixes
This commit is contained in:
@@ -21,4 +21,4 @@ Distributed under the [Boost Software License, Version 1.0](http://www.boost.org
|
||||
|
||||
### Dependency
|
||||
|
||||
This library requires boost 1.62. Since this is not released yet you can clone the winapi module from [here](https://github.com/boostorg/winapi) to get it to work. You will need to overwrite the current code in boost/libs/winapi.
|
||||
This library requires boost 1.63. Since this is not released yet you can clone the winapi module from [here](https://github.com/boostorg/winapi) to get it to work. You will need to overwrite the current code in boost/libs/winapi.
|
||||
|
||||
@@ -51,7 +51,7 @@ namespace bp = boost::process; //we will assume this for all further examples
|
||||
bp::system("g++ main.cpp");
|
||||
```
|
||||
|
||||
The first thing we can do, is to seperate the command and the executable into
|
||||
The first thing we can do, is to separate the command and the executable into
|
||||
two parts, so it is more readable and can be built by a function.
|
||||
|
||||
```
|
||||
|
||||
@@ -71,7 +71,7 @@ struct async_builder
|
||||
{
|
||||
boost::asio::io_service * ios;
|
||||
|
||||
void operator()(boost::asio::io_service & ios) {this->ios = &ios;};
|
||||
void operator()(boost::asio::io_service & ios_) {this->ios = &ios_;};
|
||||
|
||||
typedef api::io_service_ref result_type;
|
||||
api::io_service_ref get_initializer() {return api::io_service_ref (*ios);};
|
||||
|
||||
@@ -184,27 +184,27 @@ public:
|
||||
WriteHandler && handler);
|
||||
|
||||
///Get the asio handle of the pipe sink.
|
||||
const handle_type & sink () const;
|
||||
const handle_type & sink () const &;
|
||||
///Get the asio handle of the pipe source.
|
||||
const handle_type & source() const;
|
||||
const handle_type & source() const &;
|
||||
|
||||
///Get the asio handle of the pipe sink.
|
||||
handle_type && sink () &&;
|
||||
///Get the asio handle of the pipe source.
|
||||
handle_type && source() &&;
|
||||
|
||||
/// Move the source out of this class and change the io_service. Qualified as rvalue. \attention Will always move.
|
||||
handle_type source(::boost::asio::io_service& ios) &&;
|
||||
/// Move the sink out of this class and change the io_service. Qualified as rvalue. \attention Will always move
|
||||
handle_type sink (::boost::asio::io_service& ios) &&;
|
||||
|
||||
/// Copy the source out of this class and change the io_service. \attention Will always copy.
|
||||
handle_type source(::boost::asio::io_service& ios) const &;
|
||||
/// Copy the sink out of this class and change the io_service. \attention Will always copy
|
||||
handle_type sink (::boost::asio::io_service& ios) const &;
|
||||
|
||||
|
||||
///Steal, i.e. move, the source out of this class.
|
||||
handle_type steal_source();
|
||||
///Steal, i.e. move the sink out of this class.
|
||||
handle_type steal_sink();
|
||||
|
||||
///Steal, i.e. move, the source out of this class and change the io_service.
|
||||
handle_type steal_source(::boost::asio::io_service& ios);
|
||||
///Steal, i.e. move, the sink out of this class and change the io_service.
|
||||
handle_type steal_sink (::boost::asio::io_service& ios);
|
||||
///Clone the source.
|
||||
handle_type clone_source() const;
|
||||
///Clone the sink.
|
||||
handle_type clone_sink() const;
|
||||
///Clone the source and replace the io_service.
|
||||
handle_type clone_source(::boost::asio::io_service& ios) const;
|
||||
///Clone the sink and replace the io_service.
|
||||
handle_type clone_sink (::boost::asio::io_service& ios) const
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
@@ -151,40 +151,31 @@ public:
|
||||
}
|
||||
|
||||
|
||||
const handle_type & sink () const {return _sink;}
|
||||
const handle_type & source() const {return _source;}
|
||||
const handle_type & sink () const & {return _sink;}
|
||||
const handle_type & source() const & {return _source;}
|
||||
|
||||
handle_type steal_source() { return steal_source(_source.get_io_service()); }
|
||||
handle_type steal_sink() { return steal_sink(_sink.get_io_service()); }
|
||||
handle_type && source()&& { return std::move(_sink); }
|
||||
handle_type && sink() && { return std::move(_source); }
|
||||
|
||||
handle_type steal_source(::boost::asio::io_service& ios)
|
||||
handle_type source(::boost::asio::io_service& ios) &&
|
||||
{
|
||||
::boost::asio::posix::stream_descriptor stolen(ios, _source.native_handle());
|
||||
_source.assign(-1);
|
||||
return stolen;
|
||||
}
|
||||
handle_type steal_sink (::boost::asio::io_service& ios)
|
||||
handle_type sink (::boost::asio::io_service& ios) &&
|
||||
{
|
||||
::boost::asio::posix::stream_descriptor stolen(ios, _sink.native_handle());
|
||||
_sink.assign(-1);
|
||||
return stolen;
|
||||
}
|
||||
|
||||
handle_type clone_source() const
|
||||
{
|
||||
return clone_source(const_cast<handle_type&>(_source).get_io_service());
|
||||
}
|
||||
handle_type clone_sink() const
|
||||
{
|
||||
return clone_sink(const_cast<handle_type&>(_sink).get_io_service());
|
||||
}
|
||||
|
||||
handle_type clone_source(::boost::asio::io_service& ios) const
|
||||
handle_type source(::boost::asio::io_service& ios) const &
|
||||
{
|
||||
auto source_in = const_cast<::boost::asio::posix::stream_descriptor &>(_source).native();
|
||||
return ::boost::asio::posix::stream_descriptor(ios, ::dup(source_in));
|
||||
}
|
||||
handle_type clone_sink (::boost::asio::io_service& ios) const
|
||||
handle_type sink (::boost::asio::io_service& ios) const &
|
||||
{
|
||||
auto sink_in = const_cast<::boost::asio::posix::stream_descriptor &>(_sink).native();
|
||||
return ::boost::asio::posix::stream_descriptor(ios, ::dup(sink_in));
|
||||
|
||||
@@ -88,7 +88,7 @@ struct async_in_buffer : ::boost::process::detail::windows::async_handler
|
||||
});
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
template <typename WindowsExecutor>
|
||||
void on_setup(WindowsExecutor &exec)
|
||||
{
|
||||
|
||||
@@ -106,7 +106,7 @@ struct async_out_buffer : ::boost::process::detail::windows::async_handler
|
||||
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
template <typename WindowsExecutor>
|
||||
void on_setup(WindowsExecutor &exec)
|
||||
{
|
||||
@@ -181,7 +181,7 @@ struct async_out_future : ::boost::process::detail::windows::async_handler
|
||||
|
||||
});
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
template <typename WindowsExecutor>
|
||||
void on_setup(WindowsExecutor &exec)
|
||||
|
||||
@@ -164,35 +164,26 @@ public:
|
||||
_sink.async_write_some(buffers, std::forward<WriteHandler>(handler));
|
||||
}
|
||||
|
||||
const handle_type & sink () const {return _sink;}
|
||||
const handle_type & source() const {return _source;}
|
||||
const handle_type & sink () const & {return _sink;}
|
||||
const handle_type & source() const & {return _source;}
|
||||
|
||||
handle_type steal_source() { return steal_source(_source.get_io_service()); }
|
||||
handle_type steal_sink() { return steal_sink(_sink.get_io_service()); }
|
||||
handle_type && source() && { return std::move(_source); }
|
||||
handle_type && sink() && { return std::move(_sink); }
|
||||
|
||||
handle_type steal_source(::boost::asio::io_service& ios)
|
||||
handle_type source(::boost::asio::io_service& ios) &&
|
||||
{
|
||||
::boost::asio::windows::stream_handle stolen(ios, _source.native_handle());
|
||||
_source.assign(::boost::detail::winapi::INVALID_HANDLE_VALUE_);
|
||||
return stolen;
|
||||
}
|
||||
handle_type steal_sink (::boost::asio::io_service& ios)
|
||||
handle_type sink (::boost::asio::io_service& ios) &&
|
||||
{
|
||||
::boost::asio::windows::stream_handle stolen(ios, _sink.native_handle());
|
||||
_sink.assign(::boost::detail::winapi::INVALID_HANDLE_VALUE_);
|
||||
return stolen;
|
||||
}
|
||||
|
||||
handle_type clone_source() const
|
||||
{
|
||||
return clone_source(const_cast<handle_type&>(_source).get_io_service());
|
||||
}
|
||||
handle_type clone_sink() const
|
||||
{
|
||||
return clone_sink(const_cast<handle_type&>(_sink).get_io_service());
|
||||
}
|
||||
|
||||
handle_type clone_source(::boost::asio::io_service& ios) const
|
||||
handle_type source(::boost::asio::io_service& ios) const &
|
||||
{
|
||||
auto proc = ::boost::detail::winapi::GetCurrentProcess();
|
||||
|
||||
@@ -208,7 +199,7 @@ public:
|
||||
|
||||
return ::boost::asio::windows::stream_handle(ios, source);
|
||||
}
|
||||
handle_type clone_sink (::boost::asio::io_service& ios) const
|
||||
handle_type sink (::boost::asio::io_service& ios) const &
|
||||
{
|
||||
auto proc = ::boost::detail::winapi::GetCurrentProcess();
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
else
|
||||
throw std::system_error(ec, "WriteFile failed");
|
||||
}
|
||||
return write_len;
|
||||
return static_cast<int_type>(write_len);
|
||||
}
|
||||
int_type read(char_type * data, int_type count)
|
||||
{
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
else
|
||||
throw std::system_error(ec, "ReadFile failed");
|
||||
}
|
||||
return read_len;
|
||||
return static_cast<int_type>(read_len);
|
||||
}
|
||||
|
||||
bool is_open()
|
||||
|
||||
@@ -82,14 +82,14 @@ struct child_handle
|
||||
::boost::detail::winapi::BOOL_ value;
|
||||
if (!::boost::detail::winapi::IsProcessInJob(proc_info.hProcess, nullptr, &value))
|
||||
throw_last_error("IsProcessinJob Failed");
|
||||
return value;
|
||||
return value!=0;
|
||||
}
|
||||
bool in_group(std::error_code &ec) const noexcept
|
||||
{
|
||||
::boost::detail::winapi::BOOL_ value;
|
||||
if (!::boost::detail::winapi::IsProcessInJob(proc_info.hProcess, nullptr, &value))
|
||||
ec = get_last_error();
|
||||
return value;
|
||||
return value!=0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@ inline void basic_environment_impl<Char>::set(const string_type &id, const strin
|
||||
{
|
||||
reset(id);
|
||||
|
||||
std::vector<char> insertion;
|
||||
std::vector<Char> insertion;
|
||||
|
||||
insertion.insert(insertion.end(), id.begin(), id.end());
|
||||
insertion.push_back('=');
|
||||
|
||||
@@ -175,13 +175,13 @@ public:
|
||||
|
||||
child operator()()
|
||||
{
|
||||
on_setup_t on_setup(*this);
|
||||
boost::fusion::for_each(seq, on_setup);
|
||||
on_setup_t on_setup_fn(*this);
|
||||
boost::fusion::for_each(seq, on_setup_fn);
|
||||
|
||||
if (_ec)
|
||||
{
|
||||
on_error_t on_error(*this, _ec);
|
||||
boost::fusion::for_each(seq, on_error);
|
||||
on_error_t on_error_fn(*this, _ec);
|
||||
boost::fusion::for_each(seq, on_error_fn);
|
||||
return child();
|
||||
}
|
||||
|
||||
@@ -203,8 +203,8 @@ public:
|
||||
if (err_code != 0)
|
||||
{
|
||||
_ec.clear();
|
||||
on_success_t on_success(*this);
|
||||
boost::fusion::for_each(seq, on_success);
|
||||
on_success_t on_success_fn(*this);
|
||||
boost::fusion::for_each(seq, on_success_fn);
|
||||
}
|
||||
else
|
||||
set_error(::boost::process::detail::get_last_error(),
|
||||
@@ -212,8 +212,8 @@ public:
|
||||
|
||||
if ( _ec)
|
||||
{
|
||||
on_error_t on_error(*this, _ec);
|
||||
boost::fusion::for_each(seq, on_error);
|
||||
on_error_t on_err(*this, _ec);
|
||||
boost::fusion::for_each(seq, on_err);
|
||||
return child();
|
||||
}
|
||||
else
|
||||
|
||||
@@ -143,14 +143,14 @@ struct group_handle
|
||||
if (!::boost::detail::winapi::IsProcessInJob(proc, _job_object, &is))
|
||||
throw_last_error();
|
||||
|
||||
return is;
|
||||
return is!=0;
|
||||
}
|
||||
bool has(handle_t proc, std::error_code & ec) noexcept
|
||||
{
|
||||
::boost::detail::winapi::BOOL_ is;
|
||||
if (!::boost::detail::winapi::IsProcessInJob(proc, _job_object, &is))
|
||||
ec = get_last_error();
|
||||
return is;
|
||||
return is!=0;
|
||||
}
|
||||
|
||||
bool valid() const
|
||||
@@ -180,7 +180,7 @@ inline bool in_group()
|
||||
if (!::boost::detail::winapi::IsProcessInJob(boost::detail::winapi::GetCurrentProcess(), nullptr, &res))
|
||||
throw_last_error("IsProcessInJob failed");
|
||||
|
||||
return res;
|
||||
return res!=0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ struct async_handler_collector
|
||||
void operator()(T & t) const
|
||||
{
|
||||
handlers.push_back(t.on_exit_handler(exec));
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
//Also set's up waiting for the exit, so it can close async stuff.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#define BOOST_PROCESS_DETAIL_WINDOWS_LOCALE_HPP_
|
||||
|
||||
#include <locale>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
#include <boost/detail/winapi/file_management.hpp>
|
||||
#include <boost/detail/winapi/character_code_conversion.hpp>
|
||||
|
||||
@@ -39,6 +40,7 @@ class windows_file_codecvt
|
||||
const char* from, const char* from_end, const char*& from_next,
|
||||
wchar_t* to, wchar_t* to_end, wchar_t*& to_next) const override
|
||||
{
|
||||
boost::ignore_unused(state);
|
||||
::boost::detail::winapi::UINT_ codepage = AreFileApisANSI() ?
|
||||
::boost::detail::winapi::CP_ACP_ :
|
||||
::boost::detail::winapi::CP_OEMCP_;
|
||||
@@ -46,7 +48,7 @@ class windows_file_codecvt
|
||||
int count;
|
||||
if ((count = ::boost::detail::winapi::MultiByteToWideChar(codepage,
|
||||
::boost::detail::winapi::MB_PRECOMPOSED_, from,
|
||||
from_end - from, to, to_end - to)) == 0)
|
||||
static_cast<int>(from_end - from), to, static_cast<int>(to_end - to))) == 0)
|
||||
{
|
||||
return error; // conversion failed
|
||||
}
|
||||
@@ -61,6 +63,7 @@ class windows_file_codecvt
|
||||
const wchar_t* from, const wchar_t* from_end, const wchar_t*& from_next,
|
||||
char* to, char* to_end, char*& to_next) const override
|
||||
{
|
||||
boost::ignore_unused(state);
|
||||
auto codepage = ::boost::detail::winapi::AreFileApisANSI() ?
|
||||
::boost::detail::winapi::CP_ACP_ :
|
||||
::boost::detail::winapi::CP_OEMCP_;
|
||||
@@ -68,7 +71,7 @@ class windows_file_codecvt
|
||||
int count;
|
||||
if ((count = ::boost::detail::winapi::WideCharToMultiByte(codepage,
|
||||
::boost::detail::winapi::WC_NO_BEST_FIT_CHARS_, from,
|
||||
from_end - from, to, to_end - to, 0, 0)) == 0)
|
||||
static_cast<int>(from_end - from), to, static_cast<int>(to_end - to), 0, 0)) == 0)
|
||||
{
|
||||
return error; // conversion failed
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ struct on_exit_ : boost::process::detail::windows::async_handler
|
||||
handler(static_cast<int>(exit_code), ec);
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
namespace boost { namespace process { namespace detail { namespace windows {
|
||||
|
||||
class group_handle;
|
||||
struct group_handle;
|
||||
|
||||
inline void wait(const group_handle &p)
|
||||
{
|
||||
|
||||
@@ -54,8 +54,8 @@ struct const_entry
|
||||
return string_type();
|
||||
}
|
||||
string_type get_name() const {return string_type(_name.begin(), _name.end());}
|
||||
explicit const_entry(string_type&& name, pointer data, environment_t & env) :
|
||||
_name(std::move(name)), _data(data), _env(&env) {}
|
||||
explicit const_entry(string_type&& name, pointer data, environment_t & env_) :
|
||||
_name(std::move(name)), _data(data), _env(&env_) {}
|
||||
|
||||
explicit const_entry(string_type &&name, environment_t & env) :
|
||||
_name(std::move(name)), _data(nullptr), _env(&env) {}
|
||||
|
||||
@@ -183,7 +183,9 @@ struct basic_pipebuf : std::basic_streambuf<CharT, Traits>
|
||||
|
||||
|
||||
auto len = &_read.back() - this->egptr() ;
|
||||
auto res = _pipe.read(this->egptr(), len);
|
||||
auto res = _pipe.read(
|
||||
this->egptr(),
|
||||
static_cast<typename pipe_type::int_type>(len));
|
||||
if (res == 0)
|
||||
return traits_type::eof();
|
||||
|
||||
@@ -198,10 +200,12 @@ struct basic_pipebuf : std::basic_streambuf<CharT, Traits>
|
||||
void pipe(pipe_type&& p) {_pipe = std::move(p); }
|
||||
///Set the pipe of the streambuf.
|
||||
void pipe(const pipe_type& p) {_pipe = p; }
|
||||
///Get a const reference of the pipe.
|
||||
const pipe_type &pipe() const {return _pipe;}
|
||||
///Get a reference of the pipe. \note Is a reference so it can be moved.
|
||||
pipe_type &pipe() {return _pipe;}
|
||||
///Get a reference to the pipe.
|
||||
pipe_type & pipe() & {return _pipe;}
|
||||
///Get a const reference to the pipe.
|
||||
const pipe_type &pipe() const & {return _pipe;}
|
||||
///Get a rvalue reference to the pipe. Qualified as rvalue.
|
||||
pipe_type && pipe() && {return std::move(_pipe);}
|
||||
private:
|
||||
pipe_type _pipe;
|
||||
std::vector<char_type> _write;
|
||||
@@ -213,7 +217,8 @@ private:
|
||||
return false;
|
||||
|
||||
auto base = this->pbase();
|
||||
auto wrt = _pipe.write(base, this->pptr() - base);
|
||||
auto wrt = _pipe.write(base,
|
||||
static_cast<typename pipe_type::int_type>(this->pptr() - base));
|
||||
std::ptrdiff_t diff = this->pptr() - base;
|
||||
|
||||
if (wrt < diff)
|
||||
@@ -293,10 +298,12 @@ public:
|
||||
void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
|
||||
///Set the pipe of the streambuf.
|
||||
void pipe(const pipe_type& p) {_buf.pipe(p); }
|
||||
///Get a const reference of the pipe.
|
||||
const pipe_type &pipe() const {return _buf.pipe();}
|
||||
///Get a reference of the pipe. \note Is a reference so it can be moved.
|
||||
pipe_type &pipe() {return _buf.pipe();}
|
||||
///Get a reference to the pipe.
|
||||
pipe_type & pipe() & {return _buf.pipe();}
|
||||
///Get a const reference to the pipe.
|
||||
const pipe_type &pipe() const & {return _buf.pipe();}
|
||||
///Get a rvalue reference to the pipe. Qualified as rvalue.
|
||||
pipe_type && pipe() && {return std::move(_buf).pipe();}
|
||||
};
|
||||
|
||||
typedef basic_ipstream<char> ipstream;
|
||||
@@ -365,10 +372,12 @@ public:
|
||||
void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
|
||||
///Set the pipe of the streambuf.
|
||||
void pipe(const pipe_type& p) {_buf.pipe(p); }
|
||||
///Get a const reference of the pipe.
|
||||
const pipe_type &pipe() const {return _buf.pipe();}
|
||||
///Get a reference of the pipe. \note Is a reference so it can be moved.
|
||||
pipe_type &pipe() {return _buf.pipe();}
|
||||
///Get a reference to the pipe.
|
||||
pipe_type & pipe() & {return _buf.pipe();}
|
||||
///Get a const reference to the pipe.
|
||||
const pipe_type &pipe() const & {return _buf.pipe();}
|
||||
///Get a rvalue reference to the pipe. Qualified as rvalue.
|
||||
pipe_type && pipe() && {return std::move(_buf).pipe();}
|
||||
};
|
||||
|
||||
typedef basic_opstream<char> opstream;
|
||||
@@ -438,10 +447,12 @@ public:
|
||||
void pipe(pipe_type&& p) {_buf.pipe(std::move(p)); }
|
||||
///Set the pipe of the streambuf.
|
||||
void pipe(const pipe_type& p) {_buf.pipe(p); }
|
||||
///Get a const reference of the pipe.
|
||||
const pipe_type &pipe() const {return _buf.pipe();}
|
||||
///Get a reference of the pipe. \note Is a reference so it can be moved.
|
||||
pipe_type &pipe() {return _buf.pipe();}
|
||||
///Get a reference to the pipe.
|
||||
pipe_type & pipe() & {return _buf.pipe();}
|
||||
///Get a const reference to the pipe.
|
||||
const pipe_type &pipe() const & {return _buf.pipe();}
|
||||
///Get a rvalue reference to the pipe. Qualified as rvalue.
|
||||
pipe_type && pipe() && {return std::move(_buf).pipe();}
|
||||
};
|
||||
|
||||
typedef basic_pstream<char> pstream;
|
||||
|
||||
@@ -16,7 +16,8 @@ if [ os.name ] = NT
|
||||
}
|
||||
|
||||
project : requirements
|
||||
<toolset>msvc:<define>_SCL_5SECURE_NO_WARNINGS
|
||||
<toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
|
||||
<toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
|
||||
<target-os>windows:<define>WIN32_LEAN_AND_MEAN
|
||||
<target-os>linux:<linkflags>-lpthread
|
||||
<os>NT,<toolset>cw:<library>ws2_32
|
||||
@@ -38,14 +39,14 @@ alias coroutine : /boost//coroutine : <link>static ;
|
||||
exe sparring_partner : sparring_partner.cpp program_options system filesystem iostreams :
|
||||
<warnings>off
|
||||
;
|
||||
|
||||
exe sub_launch : sub_launcher.cpp program_options iostreams system filesystem : <warnings>off ;
|
||||
|
||||
exe sub_launch : sub_launcher.cpp program_options iostreams system filesystem : <warnings>off ;
|
||||
|
||||
test-suite bare :
|
||||
[ run environment.cpp system filesystem ]
|
||||
[ run pipe.cpp system filesystem ]
|
||||
;
|
||||
|
||||
|
||||
test-suite execution :
|
||||
[ run async.cpp system thread filesystem : : sparring_partner ]
|
||||
[ run async_fut.cpp system thread filesystem : : sparring_partner ]
|
||||
|
||||
Reference in New Issue
Block a user