Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What math operators are available in metaprogramming

I was quite impressed to see the final example in Todd Veldhuizen's metaprogramming guide where trig functions like sin and cos are pre-calculated at compile time. To be honest it blew me away and if you are writing code that performs a tremendous number of these in loops, as I am, then this could have a substantial effect on increased performance.

Question 1

However, it led me to wonder where the line is drawn between what is available as a run-time tool (calling actual math library functions like sin or cos) and what is available as only a compile-time mathematical operator.

Todd's example needs to manually calculate the trig function using just ordinary arithmetic.

Am I to assume then that a compiler is capable of all ordinary math functions * + - / but nothing else?

Question 2

In such a case, you'd only be able to get compile-time results for sin and cos calculations on whole numbers, right? That is, you cannot pre-compile the result of something like sin 45.5, correct?

Or perhaps if the template can only accept integers as parameters, you can take several integers and make a float out of them in the class, like passing 1 2 3 and making 1.23 to get the sin of a float value.

like image 539
johnbakers Avatar asked May 27 '13 05:05

johnbakers


1 Answers

Question 1

However, it led me to wonder where the line is drawn between what is available as a run-time tool (calling actual math library functions like sin or cos) and what is available as only a compile-time mathematical operator.

  • Named functions can only be used at compiletime if they are declared constexpr, obey the rules of constexpr and are called with compiletime constants.
  • User defined datatypes can be used at compiletime only if they are constructed via constexpr constructors from compiletime constants.
  • Any builtin operator that operates on compiletime constant builtin types gives a compiletime constant.
  • Any type conversion between builtins gives a compiletime constant, if the original is a compiletime constant.

So, it's not limited to the four mathematical operators, you can use % and other operators as well, as well as template metafunctions and constexpr expressions.

Question 2

In such a case, you'd only be able to get compile-time results for sin and cos calculations on whole numbers, right? That is, you cannot pre-compile the result of something like sin 45.5, correct?

Yes and no. In C++03 you are limited to builtins and template metafunctions, constexpr is not available. The sin therefore has to be a template metafunction that can only work on integral constants, since floating point types are not allowed in templates. You could however define templates for fractions or fixed point values and come up with a sin template for those. That would be pretty tedious though and you could easily end up running into template instantiation limitations.

Since C++11 you can write constexpr functions that take floating point parameters and work with those.

like image 51
Arne Mertz Avatar answered Oct 21 '22 06:10

Arne Mertz