Am 07.11.2016 um 21:09 schrieb Nat Goodspeed:
On Sun, Nov 6, 2016 at 11:59 AM, Boris Schäling
wrote: While Klemens made some changes to the version I handed over to him and made his own steps forward, I helped him avoiding making steps backwards. Boris, I believe you're saying that Boost.Process 0.6 is just as extensible as your 0.5, and that I should stop worrying about that point. Thank you.
However there are two points that still bother me:
* Klemens says that the dynamic-container-of-initializers idea will not work in Process 0.6. I'm not sure why. Process 0.5 initializers also used templated executor arguments; it's true that the any_initializer adapter had to state a specific executor type. (I had distinct windows vs. posix any_initializer types.) Nonetheless any_initializer could still be used with any templated initializer type. Isn't that still true? You're right, those were templated too. BUT the executor was actually not a template, so you could've written on_success(windows::executor& e). That is now different. I don't know how a type erasure could be done here, but I could write a variant. The reason is, that some properties/initializers require access the the sequence, mainly to obtain the reference of the io_service.
* Klemens states that the machinery needed to write custom initializers is currently in the detail namespace. I want it to be promoted out of the detail namespace: I want support for custom initializers to be a documented, supported feature of the library. If the library is not yet "done" in that respect, then let's consider it again when it's more fully baked. Ok, so you have three things you can do: use custom handler for events, as in
child c("foo", on_error([](auto & exec, const std::error_code & ec){std::cerr << ec.message() << std::endl;}); which is already public & documented (or at least mentioned in the documentation). Secondly there is the basic inheritance of "handler" (currently private, but needlessly so) struct foo : boost::process::detail::handler { template<typename Exec> void on_error(Exec & exec, const std::error_code & ec) { std::cerr << ec.message() << std::endl;} }; }; foo f; child c("foo", foo); This has additional features like async_handler, where you can write an on_exit handler etc. and there's a function which get's the passed io-service; so it's a bit more rich than in 0.5. Now the third option (and most complicated) would be that you declare a tag for a type, provide a builder and a initializer. I won't explain that here in detail, but let's say "foo" can be internally constructed from a sequence of "bar". Then you could us it this way: bar b1, b2; child c("bar", b1, b2); //equal too something like foo f = {b1, b2}; child c("bar", f); The reason this is not public, is because I'm not sure what should be public and what not and I'm not sure if it works as a public interface the way it does internally. I think that needs some experience from someone other than me, actually implementing an extension, to know that. I didn't think that it would've been the best idea to put this in the version of the library to be reviewed, especially since I need the experience of someone else. I really think it makes much more sense to get the library accepted in its structure before we - and by we I mean me and a user, e.g. you, - work out the details of the public extension interface.