arguments.hpp 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #pragma once
  2. #include <reproc++/detail/array.hpp>
  3. #include <reproc++/detail/type_traits.hpp>
  4. namespace reproc {
  5. class arguments : public detail::array {
  6. public:
  7. arguments(const char *const *argv) // NOLINT
  8. : detail::array(argv, false)
  9. {}
  10. /*!
  11. `Arguments` must be iterable as a sequence of strings. Examples of types that
  12. satisfy this requirement are `std::vector<std::string>` and
  13. `std::array<std::string>`.
  14. `arguments` has the same restrictions as `argv` in `reproc_start` except
  15. that it should not end with `NULL` (`start` allocates a new array which
  16. includes the missing `NULL` value).
  17. */
  18. template <typename Arguments,
  19. typename = detail::enable_if_not_char_array<Arguments>>
  20. arguments(const Arguments &arguments) // NOLINT
  21. : detail::array(from(arguments), true)
  22. {}
  23. private:
  24. template <typename Arguments>
  25. static const char *const *from(const Arguments &arguments);
  26. };
  27. template <typename Arguments>
  28. const char *const *arguments::from(const Arguments &arguments)
  29. {
  30. using size_type = typename Arguments::value_type::size_type;
  31. const char **argv = new const char *[arguments.size() + 1];
  32. std::size_t current = 0;
  33. for (const auto &argument : arguments) {
  34. char *string = new char[argument.size() + 1];
  35. argv[current++] = string;
  36. for (size_type i = 0; i < argument.size(); i++) {
  37. *string++ = argument[i];
  38. }
  39. *string = '\0';
  40. }
  41. argv[current] = nullptr;
  42. return argv;
  43. }
  44. }