Is it possible to create a variational tuple from a string?

constexpr std::tuple<int,char,int,char> t1 = parse("1a2b");
constexpr std::tuple<int,int,int,char> t2 = parse("123a");
constexpr std::tuple<char,int> t3 = parse("a2");

      

Is this possible?

I'm not quite fluent with TMP, but I started with the following

template<std::size_t N,typename ...Args> constexpr
std::tuple<Args...> parse(const char* s[N]){
  constexpr char c = s[0];
  constexpr char* new_s[N-1] = "";
  for (int i = 1; i < N; i++) {
    new_s[i] = s[i];
  }
  //my own constexpr isdigit
  if(!isdigit(c)){
    return parse(new_s,c);
  }
  else if(isdigit(c)){
    return parse(new_s,static_cast<int>(c));
  }
  throw std::invalid_argument("");
}
...

      

I wanted to do this recursively and accumulate the tuple, but I quickly realized that every time I pass a new tuple the type will change.

+3


source to share


1 answer


Since it parse

must return different types for "1a2b"

and "123a"

, it is obvious that characters containing a string literal must be part of the template parameters. It's pretty easy to do something like

constexpr bool my_isdigit(char c){
    return c >= '0' && c <= '9';
}
template<char c, bool = my_isdigit(c)>
struct mapper {
    using type = char;
    static constexpr char value = c;
};

template<char c>
struct mapper<c, true> {
    using type = int;
    static constexpr int value = c - '0';
};

template<char... chars> 
constexpr auto parse(){
    return std::tuple<typename mapper<chars>::type...>(mapper<chars>::value...);
}

constexpr auto p = parse<'1', 'a', '2', 'b'>();

      



If you really want to use string literals, there are tricks that allow you to explode a string literal into an options package .

+5


source







All Articles