Jump to content
  • Advertisement
Shaarigan

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

Recommended Posts

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

Share this post


Link to post
Share on other sites
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

Share this post


Link to post
Share on other sites

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

Edited by Shaarigan
Changed code example for Bregma's answer

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!