JeffGarland / liaw2019-process

Repository for initial drafting of boost.process standards paper
MIT License
5 stars 4 forks source link

Belfast LEWGI: Make all concepts sets of named requirements instead #49

Open eliaskosunen opened 4 years ago

eliaskosunen commented 4 years ago

Specifying a concept, even an exposition only one, gives implementers no leeway. We must use a table of named requirements instead, unfortunately.

JeffGarland commented 4 years ago

I've gotten feedback from other committee members on this and lets say the feedback isn't universal. I think a good compromise would be to convert to exposition only for string type and maybe leave the launcher since it's actually a customization point. But still tbd.

klemens-morgenstern commented 4 years ago

After finally getting to play with gcc 10 & concepts (https://gcc.godbolt.org/z/pgUe8q), I agree with half, namely the removal of process_argument_list, but we should keep process_launcher. I am not sure about process_initializer

The reason I would want to keep the process_launcher is so I can use it in my extensions:

struct my_thingy {
   template<process_launcher launcher>
    void on_setup(launcher ) { /* ... */ }
}

The argument for this extension should have guarantees in regards to it's type. Now, this might not be absolutely necessary, but I tend to think that actually expressing the intent / guarantee makes a log of sense.

klemens-morgenstern commented 4 years ago

I can't figure out how to inline the process_launcher but we can turn it into an implementation detail.

namespace std {

class process;

template<typename Launcher, typename Init>
concept _process_initializer =
    (  requires(Init initializer, Launcher launcher) { {initializer.on_setup(launcher)}; }
    || requires(Init initializer, Launcher launcher) { {initializer.on_success(launcher)}; }
    || requires(Init initializer, Launcher launcher) { {initializer.on_error(launcher, error_code())}; }
    );

template<typename Launcher, typename Args = vector<string>, typename ...Initializers>
concept process_launcher = 
    (
        convertible_to<iter_value_t<ranges::iterator_t<Args>>, string_view> ||
        convertible_to<iter_value_t<ranges::iterator_t<Args>>, wstring_view> ||
        convertible_to<iter_value_t<ranges::iterator_t<Args>>, u8string_view>
    )  &&
    requires(Launcher launcher, Args a, filesystem::path p, Initializers ... initializers) {
            { launcher.set_error(error_code(), "message") };
            { launcher.launch(p, a, initializers...) } -> std::same_as<process>;
        }
        &&  (_process_initializer<Launcher, Initializers> &&  ...);
}