File indexing completed on 2024-12-15 05:02:06
0001 /* 0002 SPDX-FileCopyrightText: 2018 Ivan Čukić <ivan.cukic(at)kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #ifndef VOY_WRAPPERS_PROCESS_H 0008 #define VOY_WRAPPERS_PROCESS_H 0009 0010 // STL 0011 #include <vector> 0012 #include <functional> 0013 0014 // Self 0015 #include "../utils.h" 0016 #include "../traits.h" 0017 #include "../dsl/node_tags.h" 0018 #include "../engine/asio/process.h" 0019 0020 namespace voy { 0021 0022 using voy::utils::non_copyable; 0023 0024 template <typename ValueHandler, typename... Args> 0025 class process_impl: public non_copyable { 0026 public: 0027 using node_category = dsl::source_node_tag; 0028 0029 explicit process_impl(std::tuple<Args...> command, 0030 ValueHandler handler = voy::utils::identity{}) 0031 : m_command{std::move(command)} 0032 , m_handler{std::move(handler)} 0033 { 0034 } 0035 0036 template <typename Cont> 0037 class node: non_copyable { 0038 voy_assert_value_type(Cont); 0039 0040 template <typename F, typename G> 0041 struct composition { 0042 voy_assert_value_type(F); 0043 voy_assert_value_type(G); 0044 0045 F f; 0046 G g; 0047 0048 composition(F f, G g) 0049 : f{std::move(f)} 0050 , g{std::move(g)} 0051 { 0052 } 0053 0054 template <typename T> 0055 decltype(auto) operator() (T&& value) const 0056 { 0057 #define EVAL_F_G std::invoke(f, voy_fwd_invoke(g, value)) 0058 if constexpr (std::is_same_v<void, decltype(EVAL_F_G)>) { 0059 EVAL_F_G; 0060 } else { 0061 return EVAL_F_G; 0062 } 0063 #undef EVAL_F_G 0064 } 0065 0066 void init() 0067 { 0068 f.init(); 0069 } 0070 0071 void notify_ended() const 0072 { 0073 f.notify_ended(); 0074 } 0075 }; 0076 0077 public: 0078 using value_type = decltype(std::declval<ValueHandler>()(std::string{})); 0079 0080 node(Cont&& cont, ValueHandler&& handler, std::tuple<Args...> command) 0081 : m_process{ 0082 std::make_unique<voy::engine::asio::process<composition<Cont, ValueHandler>>>( 0083 composition<Cont, ValueHandler>{std::move(cont), std::move(handler)}, 0084 std::move(command) 0085 ) 0086 } 0087 { 0088 } 0089 0090 void init() 0091 { 0092 m_process->init_handler(); 0093 } 0094 0095 private: 0096 std::unique_ptr< 0097 voy::engine::asio::process<composition<Cont, ValueHandler>>> m_process; 0098 }; 0099 0100 0101 template <typename Cont> 0102 auto with_continuation(Cont&& cont) && 0103 { 0104 return node<Cont>( 0105 voy_fwd(cont), std::move(m_handler), std::move(m_command)); 0106 } 0107 0108 private: 0109 std::tuple<Args...> m_command; 0110 ValueHandler m_handler; 0111 }; 0112 0113 template <typename Cmd, typename... Args> 0114 auto process(Cmd&& cmd, Args&&... args) 0115 { 0116 return process_impl( 0117 std::make_tuple(voy_fwd(cmd), voy_fwd(args)...), 0118 voy::utils::identity{}); 0119 } 0120 0121 template <typename Cmd, typename... Args> 0122 auto system_cmd(Cmd&& cmd, Args&&... args) 0123 { 0124 return process(boost::process::search_path(voy_fwd(cmd)), voy_fwd(args)...); 0125 } 0126 0127 } 0128 0129 #endif // include guard 0130