Skip to content

Latest commit

 

History

History
238 lines (195 loc) · 5.41 KB

284.md

File metadata and controls

238 lines (195 loc) · 5.41 KB
Info

Example

#include <span>
#include <spanstream>
#include <iostream>

int main() {
  char input[] = "1 2 3";
  std::ispanstream is{std::span<char>{input}};
  int i1, i2, i3;
  is >> i1 >> i2 >> i3;
  std::cout << i1 << i2 << i3; // prints 123
}

https://godbolt.org/z/sxT84Mq6h

Puzzle

  • Can you implement to_tuple which converts (using ispanstream) given input into tuple of Ts...?
template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]); // TODO

int main() {
  using namespace boost::ut;

  "to_tuple.ints"_test = [] {
    char input[] = "1 2 3";
    expect(std::tuple{1, 2, 3} == to_tuple<int, int, int>(input));
  };

  "to_tuple.floats"_test = [] {
    char input[] = "1.2 2.3 3.4";
    expect(std::tuple{1.2f, 2.3f, 3.4f} == to_tuple<float, float, float>(input));
  };

  "to_tuple.mix"_test = [] {
    char input[] = "42 4.2";
    expect(std::tuple{42, 4.2d} == to_tuple<int, double>(input));
  };
}

https://godbolt.org/z/9z6T11hbq

Solutions

template<class T, class... Ts>
constexpr auto set_vals(auto tuple, auto& stream) {
  T &val = std::get<std::tuple_size_v<decltype(tuple)> - sizeof...(Ts) - 1>(tuple);
  stream >> val;
  if constexpr (sizeof...(Ts) > 0) {
    tuple = set_vals<Ts...>(tuple, stream);
  }
  return tuple;
}

template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]) {
  std::ispanstream stream{std::span<char>{input}};
  return set_vals<Ts...>(std::tuple<Ts...>{}, stream);
}

https://cpp_tip_of_the_week.godbolt.org/z/4f9ssz41x

namespace detail {

template <typename TArg>
[[nodiscard]] constexpr auto extract_arg(auto& stream) {
    TArg arg{};
    stream >> arg;
    return arg;
}

}  // namespace detail

template <class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]) {
    std::ispanstream stream{std::span<char>{input}};
    return std::tuple{detail::extract_arg<Ts>(stream)...};
}

https://godbolt.org/z/Txn53EKhY

template <class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]) {
    std::tuple<Ts...> result;
    auto& [...refs] = result;
    std::ispanstream stream{input};
    ((stream >> refs), ...);
    return result;
}

https://godbolt.org/z/jWxshM7bd

template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]) {
  constexpr auto extract = []<class T>(auto& input) -> T {
    T t{};
    input >> t;
    return t;
  };
  std::ispanstream is{input};
  return std::tuple{extract.template operator()<Ts>(is)...};
}

https://godbolt.org/z/76nd8zr1n

template <typename T> std::tuple<T> parse(std::ispanstream& is)
{
  T t; is >> t;
  return std::tuple<T>(std::move(t));
}

template <typename T, typename Arg, typename... Args>
std::tuple<T, Arg, Args...> parse(std::ispanstream& is)
{
  T t; is >> t;
  return std::tuple_cat(std::tuple<T>(std::move(t)),
                        parse<Arg, Args...>(is));
}

template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N])
{
    std::ispanstream is{std::span<char>{input}};
    return parse<Ts...>(is);
};

https://godbolt.org/z/6EsnE7joY

template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]) {
    auto stream = std::ispanstream{input};
    auto values = std::tuple<Ts...>{};
    std::apply([&](auto&... value) {
        ((stream >> value), ...);
    }, values);
    return values;
}

https://godbolt.org/z/r5E8oaW89

template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]) {
  std::ispanstream is{std::span{input}};
  std::tuple<Ts...> return_values;
  std::apply(
    [&](Ts &... elements) {
      (is >> ... >> elements);
    },
    return_values
  );
  return return_values;
};

https://godbolt.org/z/P99ss9ndG

template <class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]) {
  std::tuple<Ts...> t;
  std::apply(
      [&](Ts &...elements) {
        (std::ispanstream{std::span{input}} >> ... >> elements);
      },
      t);
  return t;
}

https://godbolt.org/z/9xxKT5qKE

template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]){
    std::ispanstream is{std::span<char>{input}};
    std::tuple<Ts...> t;
    [&]<std::size_t... Indices>(std::index_sequence<Indices...>){
        ((is >> std::get<Indices>(t)), ...);
    }(std::make_index_sequence<sizeof...(Ts)>());
    return t;
}

https://godbolt.org/z/rWhTToxxK

template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]) {
    std::ispanstream is{std::span{input, N}};
    std::tuple<Ts...> tp;
    [&is, &tp]<size_t... I>(std::index_sequence<I...> const&) {
        ((is >> std::get<I>(tp)), ...);
    }(std::index_sequence_for<Ts...>{});
    return tp;
}

https://godbolt.org/z/K8oonfWv7

template<class... Ts, auto N>
[[nodiscard]] constexpr auto to_tuple(char (&input)[N]){
    std::tuple<Ts...> my_tuple;
    std::apply(
        [&](Ts& ... args){
            (std::ispanstream{std::span{input}} >> ... >> args);
        }, my_tuple
    );
    return my_tuple;
}

https://godbolt.org/z/f3WsEc1WE