2

I'd like to check a value at compile time, if it's a constexpr value and do run a constexpr form-checking function on it if it is.

Can I do this in c++11/14?

In pseudo code, I'd like to do:

static_if (is_constexpr(x)) 
      static_assert(check(x))

Details:

I'm checking a string for a particular format. It's conceptually:

template<std::size_t N>
constexpr bool check(const char (&s)[N]){ return true; }
//^ really a recursive call that checks the string

The constexpr check works with a string literal, but not with a string pointer:

int main(){
  const char* s = "#";
  static_assert(check("#"), "Fmt");; //OK

  //This fails; expectation was it suceeds and the check doesn't run
  static_assert(!is_constexpr(s) || check(s), "Fmt");

}

The is_constexpr is:

#include <type_traits>
template<typename T> 
constexpr typename std::remove_reference<T>::type makeprval(T && t) {
  return t;
}
#define is_constexpr(e) noexcept(makeprval(e))
T.C.
  • 133,968
  • 17
  • 288
  • 421
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • The "duplicate" refers to producing a `bool` that holds this result. If you want to abort compilation instead, then perhaps different solutions are possible. – M.M Dec 10 '15 at 22:50
  • How about `static_assert(x || !x, "");` . If `x` is not constant this will fail to compile, and if it is constant then nothing happens. – M.M Dec 10 '15 at 22:51
  • @M.M I only want to abort compilation if the value is constexpr and my constexpr check failed. – Petr Skocik Dec 10 '15 at 22:53
  • 1
    OK, I have reopened the question as this is substantially different to the previous duplicate – M.M Dec 10 '15 at 22:54
  • The stuff in your "details" is different to your original question. `"#"` is a constant expression, but `s` is not a constant expression. – M.M Dec 10 '15 at 22:58
  • I don't understand what the line `//static_assert(/*!is_constexpr(s) ||*/ check(s), "Fmt");; //doesn't work` is supposed to be saying, could you try to write this a bit more clearly (show the actual code that "doesn't work" and explain how the behaviour differs from what you expected) – M.M Dec 10 '15 at 22:59
  • `static_assert(!is_constexpr(s) || check(s), "Fmt");` this should work -- it either shouldn't be constexpr or the constexpr check should run. I concede that the linked question is a duplicate. (Unfortunately, the proposed solution doesn't work, but that's another issue). You can close this one. – Petr Skocik Dec 10 '15 at 23:05
  • Well, it's not a duplicate IMO, but if you're happy that your problem is solved by the other thread then we can leave this – M.M Dec 10 '15 at 23:13
  • I have edited the question to reflect your last comment , and removed the stuff about the other solution not compiling. (Post a comment on the actual answer containing that code, if it doesn't work) – M.M Dec 10 '15 at 23:15
  • 1
    @PSkocik: I understand what you're trying to do, although I don't know how to do it, or if it is even possible. I think your problem is considerably more complex than the linked question, since even once `is_constexpr()` is made to work, you may still have a problem that an unevaluated part of `!is_constexpr(s) || check(s)` isn't a constant expression. Based on my understanding, you're looking to implement `static_if (is_constexpr(s)) static_assert(check(s))` – Ben Voigt Dec 10 '15 at 23:26
  • M.M seems to have missed the point repeatedly, so I've tried to undo his well-intentioned but damaging changes. If he keeps making changes you don't agree with, try starting a post on meta or raise a moderator flag. – Ben Voigt Dec 10 '15 at 23:28
  • @BenVoigt if I am missing the point, it suggests that the question could be edited to more clearly express what the point is ... perhaps you could do that – M.M Dec 11 '15 at 00:28
  • Well there's [this hack](http://baptiste-wicht.com/posts/2015/07/simulate-static_if-with-c11c14.html), that, when combined with [this other hack](http://stackoverflow.com/a/13305072/27678), could be used to produce something like [this](http://coliru.stacked-crooked.com/a/fa6ef098394973a4). Would that solve your issue? – AndyG Dec 11 '15 at 01:12
  • Well, right now your sample code does not compile because `check(s)` doesn't compile at all (there's no viable overload of `check` for `const char *`). The simplest fix for that is probably adding a `bool check(...);` overload. Is that your actual issue, or is it something else? – T.C. Dec 11 '15 at 05:15

1 Answers1

0

May be your question is bit unclearer to me. If you want whether a string literal should pass and pointer should not then look at below answer. Should you feel that, I have misunderstood your question then comment it, I shall delete this answer or modify accordingly.

You can use simple C-style macro to check if given variable is a string literal, as I have explained in my answer to below question:
Verify type of string (e.g. literal, array, pointer) passed to a function

#define IS_LITERAL(X) "" X

The compilation will fail if the X is not a string literal.

Community
  • 1
  • 1
iammilind
  • 68,093
  • 33
  • 169
  • 336