Boost logo

Boost :

Subject: Re: [boost] [process] Arguments and Context concepts
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2011-01-20 02:21:43


----- Original Message -----
From: "Boris Schaeling" <boris_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Wednesday, January 19, 2011 11:59 PM
Subject: Re: [boost] [process] Arguments and Context concepts

> On Wed, 19 Jan 2011 14:58:21 +0100, Vicente Botet
> <vicente.botet_at_[hidden]> wrote:
>
> Hi Vicente,
>
>> Where can I find the concept behind the template parameters Arguments and
>> Context in
>>
>>
>> template<typename Arguments, typename Context>
>> child create_child(const std::string & executable, Arguments args,
>> Context ctx);
>
> it should be possible to use any container for Arguments as long as its
> elements are std::strings. The flexibility regarding Context is more
> theoretical (you basically have to copy boost::process::context and can't
> leave anything out).
>
> In early versions of the library one of the goals was to support multiple
> string types. In practice nothing but std::string ever worked. There were
> once also multiple context classes when the library shipped
> platform-specific classes for POSIX and Windows. As of today
> create_child() heavily depends on boost::process::context though.

We could have multiple implementations of the same concept and have just one in a specific platform. In this case we have always the same class and having a template parameter is not realy useful. If the requirements are too close to the current context implementation, which is the advantage to pass Context as template parameter then?
 
What about adding this overloading?

template <typename Context>
child create_child(const std::string &executable, const Context & ctx);

You should need enable_if and some way to recognize if the parameter is a Context or some Arguments to disambiguate, but it should be possible, and this avoids to have an additional args variable when no args at all are needed.

BTW, are you copying the parameters Arguments and Context now? Why not pass by reference?

A see the change to the working directory as a really specific case. I would pass it as an argument to the process creation and let the child process make itself the change to the working directory. Could you tell us why did you need to added it?

An alternative to multiple overloading could be to use the essence pattern of a child process creation and pass to the function a single parametter:

child create_child(const creation_essence & );

and make the cchild reation essence a class that force the mandatory parameters at construction time.

class creation_essence {
public:
  creation_essence(const std::string &absolute_path_to_executable);
  creation_essence(const std::string &process_name, const std::string &path);
  void add_arg(const std::string &);
  void set_env(const std::string &,const std::string &);
  void set_working_dir(const std::string &);
  ... Other more efficient overloads could also be added (using const char* for example);
  // observers needed by the back end
  ...
};

So intead of the example in the doc

std::string exe = boost::process::find_executable_in_path("hostname");
std::vector<std::string> args;
boost::process::context ctx;
ctx.process_name = "hostname";
ctx.work_dir = "C:\\";
ctx.env.insert(std::make_pair("new_variable", "value"));
boost::process::create_child(exe, args, ctx);

we could have

creation_essence prm(boost::process::find_executable_in_path("hostname");
prm.set_process_name("hostname");
prm.set_working_dir("C:\\");
prm.add_env("new_variable", "value");
boost::process::create_child(prm);

or
creation_essence prm("hostname", "");
prm.set_working_dir("C:\\");
prm.set_env("new_variable", "value");
boost::process::create_child(prm);

This interface should be more close to what a DSL could need and the implementation could be more platform driven.

Boost.Parameter could also be cosidered.

HTH,
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk