String Template Parameters outside C++11/14/17

Started by
4 comments, last by Shaarigan 6 years, 2 months ago

Hey,

I was fiddling arround with RegEx-es while I tried to implement them on an old machine without using any C++11/14/17 related syntactic sugar like constexpr or variadic templates but still as compile-time evaluated statement list. But without any luck as one might already get ;)

My problem to solve is getting a convinient way to make a list of character parameters from a compile-time string literal to pass into the template based compile-time deduction process. This may look something like this


template<char a0> struct CharacterList <a0> //<<- as string???
{
   public:
      typedef Evaluator<a0> Eval;
};
template<char a0, char a1> struct CharacterList <a0a1> //<<- as string???
{
   public:
      typedef Evaluator<a0, Evaluator<a1>> Eval;
};
template<char a0, char a1, char a2> struct CharacterList <a0a1a2> //<<- as string???
{
   public:
      typedef Evaluator<a0, Evaluator<a1, Evaluator<a2>>> Eval;
};

int main()
{
    Regex r = CharacterList<"MyRegexSyntax">::Eval;
}

I know this is anything but working without the new ISO features but was corious if someone has any workarround for that except defining strings as an array of characters :D

Thanks in advance

Advertisement

Sounds like you want the compiler to parse components of a string, and generate code at compile-time based on that compile-time string, instead of generating code to emit data structures at runtime based on a runtime string.

That's the very purpose of constexpr, and AFAIK there is no standard C++ way to do that before C++17... and it might even be pretty tricky in C++20.

That said, here's someone working on the same thing: https://github.com/hanickadot/compile-time-regular-expressions

RIP GameDev.net: launched 2 unusably-broken forum engines in as many years, and now has ceased operating as a forum at all, happy to remain naught but an advertising platform with an attached social media presense, headed by a staff who by their own admission have no idea what their userbase wants or expects.Here's to the good times; shame they exist in the past.

I already saw this but as I wrote on-top

On 29.1.2018 at 2:39 PM, Shaarigan said:

I tried to implement them on an old machine without using any C++11/14/17

the drawback is that this (or better the compiler; thank you Microsoft) dosent support constexpr and is itself very ... bitchy .. (is that a word? :D )about compile time code verification. Thats why I needed to write a list of char literals instead of string even on the fact that I have a variadic macro replacement (like the one from boost) that already works and compiles oin different compilers (MSVC 2010, 2015, clang LLVM)


#ifndef LITERAL_MAX_LENGTH
#define LITERAL_MAX_LENGTH 70
#endif

struct ErrorType;

/**
 A compile time expression
*/
template<char c, typename list> struct Expression 
{ 
	typedef ErrorType Result;
};
/*
define additional expressions here
template<typename list> struct Expression<'['>
{
    typedef typename SequenceType<list::Head, List::Tail> Result;
};
*/

/**
 A compile time static literal expression
*/
template<VARIADIC_PARAMS_PAIR(char c, = 0, LITERAL_MAX_LENGTH)> struct Literal;
#define LITERAL_DEFINITION(n) template<VARIADIC_PARAMS_ARGS(char c, n)> struct Literal<VARIADIC_PARAMS_ARGS(c, n)> \
{ \
  enum { Head = (c0) }; \
  typedef typename Literal<VARIADIC_PARAMS_SHIFT(c, n)> Tail; \
 \
  typedef typename Expression<Head, Tail>::Result Compile; \
  static const char Value[n + 1]; \
}; \
template<VARIADIC_PARAMS_ARGS(char c, n)> const char Literal<VARIADIC_PARAMS_ARGS(c, n)>::Value[n + 1] = { VARIADIC_PARAMS_ARGS(c, n), 0 };

IT_FOR(DECREMENT(LITERAL_MAX_LENGTH), LITERAL_DEFINITION)

#define litexpr(...) Literal<__VA_ARGS__>
#undef LITERAL_DEFINITION
#undef LITERAL_MAX_LENGTH

But is still a bit tricky to use, even when going for the macro


litexpr('[','^',' ',']','*')::Compile //works but is ugly to use
litexpr("[^ ]*")::Compile //dosent work; MSVC complains until 2013 (constexpr isnt supported) and even sometimes in 2015 that this is not a compile time constant

What I like to achieve here is to have compile-time verified/ assembled expressions that could be used for example in a regulary test regex or something like a mesh; or in general to have compile-time expression code that is generated into runtime usable parser/verifier/lambda/<insert whatever here>. It dosent need to verify anything at compile-time but simply compile the expression into executable code. I know it is hard and tricky to get this running (and sometimes a waste of time) but its just an experimental feature to speed up things

The mechanism they introducd into C++11 to do exactly this was the template parameter pack (AKA variadic templates).  Prior to that, you could use Alexandrescu's typelists or something similar.

It's pretty much an academic exercise:  processing a regex at compile time gives you the benefit of incredible and error-time complexity at the cost of massive code bloat.  But it's nevertheless an interesting academic exercise, so carry on.

Stephen M. Webb
Professional Free Software Developer

Thank you for the typelist suggestion, that made life a little easier for this as I could now pass Head and the Tail-List arround as separate parameters. I thought about the topic and came to the conclusion that it would be a possible goal to have a list of function pointers at the end so my regex/filter/lambda class could act like


class Regex
{
   public:
      inline Regex(const StaticContext<bool (IDataStream const&)>* validator) : validator(validator)
      { }
  
  	  inline bool Match(IDataStream const& data)
      {
          StaticContext<bool (IDataStream const&)> tmp* = validator;
          while(tmp && *tmp(data))
             tmp++;
        
          return !(tmp);
      }
  
   protected:
      StaticContext<bool (IDataStream const&)> validator*;
}

In this case, we would check a set of function pointers for returning true each on some data and result if we reached the end (zero) of that list so we could be sure we found a match

This topic is closed to new replies.

Advertisement