C++ metaprogramming recursive step limit - c++

I'm giving template metaprogramming a go. Here is a simple example I came up with:
template <int n>
struct N
{
static const int k = N<n-2>::k;
};
template<>
struct N<0>
{
static const int k = 0;
};
int main(int, char *[])
{
}
The above works. Note that k is defined as k = N<n-2>::k;
The following fails:
template <int n>
struct N
{
static const int k = N<n-3>::k;
};
template<>
struct N<0>
{
static const int k = 0;
};
int main(int, char *[])
{
cout << N<10>::k;
getchar();
}
Same code, except now k = N<n-3>:k; The compiler complains about the code being too complex. This limit seems fairly arbitrary, is there a way to modify it?

Your original recursion only terminates for even values of the template parameter n. You need two stop cases, for n == 0 and n == 1. In your revised example, you'd need 3 stop cases, or a stop case for n <= 0.

Related

C++ Fixed Range Int

I'd like to create a type with a compile-time guarantee that instances are one of N possible values. The values are int types. No arithmetic needed.
One possible solution is to use an enum class, but this scales poorly with N.
I think the solution would look most like a fixed range int. I imagine the usage would look something like this, but i'm not too sure how to implement this.Is something like this possible or am I limited to enum classes?
constexpr auto N = 60;
MyType<N> foo(30); // okay
MyType<N> foo(0); // okay
MyType<N> foo(59); // okay
MyType<N> bar(60); // compile error
MyType<N> boo(-1); // compile error
I don't think it's possible to get compile error, however you can limit it using custom class something like this:
#include <stdexcept>
class MyIntger {
public:
MyIntger(int num){
if(num < Min || num > Max){
throw std::runtime_error("Number out of range");
}
value = num;
}
private:
int value;
const static int Min = 0;
const static int Max = 60;
};
int main(){
MyIntger a(5); // OK
MyIntger b(61); // Throws std::runtime_error
}
You can have compile-time ints in C++ (and thus compile-time limit checking), but syntax is not the same as for runtime ints:
#include <type_traits>
template<size_t N>
struct MyInteger
{
// you might have it as T or limit it to size_t
template<typename T, T I>
MyInteger(std::integral_constant<T, I>)
: value(I) { static_assert(I < N); }
size_t value;
};
int main()
{
MyInteger<60> a(std::integral_constant<size_t, 59>()); // ok
MyInteger<60> b(std::integral_constant<size_t, 60>()); // error
}
If you don't like the long name, you can always have a template type alias, e.g.:
template<size_t K>
std::integral_constant<size_t, K> I = {};
int main()
{
MyInteger<60> a(I<59>);
}

Parametric function in namespaces (C++)

I need to define 3 functions that have the same goal, but whose behaviours changes slightly based on 3 sets of constant values; in other words, i could simply write a function that does that in all 3 cases by taking those values as inputs. But since there really many constants (and only 3 different sets of those) i'd definitely avoid such a long function declaration. Furthermore, i'll need those sets of constants in other files for related computations.
I was thinking about using namespaces, but i couldn't find anything that suited what i wanted to achieve. Just to make things more comprehensible, here is an example of what i'd desire (but obviously doesn't compile):
int parametric_function() {
return a_constant + 1; //'a_constant' isn't defined yet
}
namespace first_behaviour {
const int a_constant = 10;
//make the function use the variable 'a_constant' defined here in some way
int (*f)() = parametric_function;
}
namespace second_behaviour {
const int a_constant = 20;
//make the function use the variable 'a_constant' defined here in some way
int (*f)() = parametric_function;
}
As you can see, i'd only need to write my parametric function once, and i can use the namespace to get the right function and the associated set of constants. Do you have any suggestions on what i could try doing?
If you have only one variable, you can pass it directly as a template parameter, as suggested in this answer.
But if you have more than one, you can wrap them in a struct:
#include <iostream>
struct FirstBehavior
{
static constexpr int a_constant = 10;
};
struct SecondBehavior
{
static constexpr int a_constant = 10;
};
template <typename T>
int ParametricFunction()
{
return T::a_constant + 1;
}
int main()
{
std::cout << ParametricFunction<FirstBehavior>() << '\n'; // 1
}
In c++ you have templates:
template <int a_constant>
int parametric_function() {
return a_constant + 1;
}
namespace first_behaviour {
auto f = parametric_function<10>;
}
Using HolyBlackCat's suggestion of a struct and a template, here would be one approach.
The struct is just a wrapper to hold the variable. In this example, I made it a stateful variable (non-const), static to the struct wrapper. It has the requirement to be the expected name by the parameteric_function.
I thought making the example use a non-const variable might be more generally applicable for other types, such as std::string or std::vector or whatever you may need.
The extern int (*f)(); was just to squelch a compiler warning.
#include <iostream>
using std::cout;
template <typename T>
int parametric_function() {
++T::a_variable;
return T::a_variable;
}
namespace first_behaviour {
struct VarHolder {
static inline int a_variable = 10;
};
extern int (*f)();
int (*f)() = &parametric_function<VarHolder>;
} // first_behaviour
namespace second_behaviour {
struct OtherVarHolder {
static inline int a_variable = 20;
};
extern int (*f)();
int (*f)() = &parametric_function<OtherVarHolder>;
} // second_behaviour
int main() {
int x = first_behaviour::f();
int y = second_behaviour::f();
cout << x << " " << y << "\n";
}
Possibly you could do with templates. You could:
template <int CONST_VAL>
int par_func();
template<>
int par_func<10>(){ return 4; }
template<>
int par_func<20>(){ return 1; }
template<>
int par_func<30>(){ return 9; }
You could then alias these names to some other function if you want, or you can leave them like this. This also ensures that only the specialisations can be used.
You can also do your example like:
template <int CONST_VAL>
int par_func(){
return CONST_VAL + 1;
}
You can then put this in an implementation file and explicilty instantiate only the ones you use, like:
template int par_func<10>();
You can use this the same way with your namespace model like:
namespace func1 {
int(* func)() = &par_func<10>;
}
namespace func2 {
int(* func)() = &par_func<20>;
}

C++ compile time array size from template function

I'm not sure why the array creation in the function passes but not the one in the class even though array size is a compile time computable value.
template<int N>
int getPow()
{
int power = 1;
while(power < N)
power <<= 1;
return power;
}
template<int N>
class Test
{
private:
int data[getPow<N>()];
};
void testfun()
{
int test[getPow<2>()]; // passes
Test<10> t1; // Fails????
}
As getPow is not constexpr, it cannot be used in places which require constant expression (as C-array size).
int test[getPow<2>()]; // passes
. You unfortunately use VLA extension. It should not pass.
You might solve your issue with:
template <unsigned N>
constexpr unsigned getPow()
{
return 1 << N;
}

Is it possible to perform a string to int mapping at compile time?

Is it possible to perform a unique string to int mapping at compile time?
Let's say I have a template like this for profiling:
template <int profilingID>
class Profile{
public:
Profile(){ /* start timer */ }
~Profile(){ /* stop timer */ }
};
which I place at the beginning of function calls like this:
void myFunction(){
Profile<0> profile_me;
/* some computations here */
}
Now I'm trying to do something like the following, which is not possible since string literals cannot be used as a template argument:
void myFunction(){
Profile<"myFunction"> profile_me; // or PROFILE("myFunction")
/* some computations here */
}
I could declare global variables to overcome this issue, but I think it would be more elegant to avoid previous declarations. A simple mapping of the form
”myFunction” → 0
”myFunction1” → 1
…
”myFunctionN” → N
would be sufficient. But to this point neither using constexpr, template meta-programming nor macros I could find a way to accomplish such a mapping. Any ideas?
As #harmic has already mentioned in the comments, you should probably just pass the name to the constructor. This might also help reduce code bloat because you don't generate a new type for each function.
However, I don't want to miss the opportunity to show a dirty hack that might be useful in situations where the string cannot be passed to the constructor. If your strings have a maximum length that is known at compile-time, you can encode them into integers. In the following example, I'm only using a single integer which limits the maximum string length to 8 characters on my system. Extending the approach to multiple integers (with the splitting logic conveniently hidden by a small macro) is left as an exercise to the reader.
The code makes use of the C++14 feature to use arbitrary control structures in constexpr functions. In C++11, you'd have to write wrap as a slightly less straight-forward recursive function.
#include <climits>
#include <cstdint>
#include <cstdio>
#include <type_traits>
template <typename T = std::uintmax_t>
constexpr std::enable_if_t<std::is_integral<T>::value, T>
wrap(const char *const string) noexcept
{
constexpr auto N = sizeof(T);
T n {};
std::size_t i {};
while (string[i] && i < N)
n = (n << CHAR_BIT) | string[i++];
return (n << (N - i) * CHAR_BIT);
}
template <typename T>
std::enable_if_t<std::is_integral<T>::value>
unwrap(const T n, char *const buffer) noexcept
{
constexpr auto N = sizeof(T);
constexpr auto lastbyte = static_cast<char>(~0);
for (std::size_t i = 0UL; i < N; ++i)
buffer[i] = ((n >> (N - i - 1) * CHAR_BIT) & lastbyte);
buffer[N] = '\0';
}
template <std::uintmax_t Id>
struct Profile
{
char name[sizeof(std::uintmax_t) + 1];
Profile()
{
unwrap(Id, name);
std::printf("%-8s %s\n", "ENTER", name);
}
~Profile()
{
std::printf("%-8s %s\n", "EXIT", name);
}
};
It can be used like this:
void
function()
{
const Profile<wrap("function")> profiler {};
}
int
main()
{
const Profile<wrap("main")> profiler {};
function();
}
Output:
ENTER main
ENTER function
EXIT function
EXIT main
In principle you can. However, I doubt any option is practical.
You can set your key type to be a constexpr value type (this excludes std::string), initializing the value type you implement is not a problem either, just throw in there a constexpr constructor from an array of chars. However, you also need to implement a constexpr map, or hash table, and a constexpr hashing function. Implementing a constexpr map is the hard part. Still doable.
You could create a table:
struct Int_String_Entry
{
unsigned int id;
char * text;
};
static const Int_String_Entry my_table[] =
{
{0, "My_Function"},
{1, "My_Function1"},
//...
};
const unsigned int my_table_size =
sizeof(my_table) / sizeof(my_table[0]);
Maybe what you want is a lookup table with function pointers.
typedef void (*Function_Pointer)(void);
struct Int_vs_FP_Entry
{
unsigned int func_id;
Function_Point p_func;
};
static const Int_vs_FP_Entry func_table[] =
{
{ 0, My_Function},
{ 1, My_Function1},
//...
};
For more completion, you can combine all three attributes into another structure and create another table.
Note: Since the tables are declared as "static const", they are assembled during compilation time.
Why not just use an Enum like:
enum ProfileID{myFunction = 0,myFunction1 = 1, myFunction2 = 2 };
?
Your strings will not be loaded in runtime, so I don't understand the reason for using strings here.
It is an interesting question.
It is possible to statically-initialize a std::map as follows:
static const std::map<int, int> my_map {{1, 2}, {3, 4}, {5, 6}};
but I get that such initialization is not what you are looking for, so I took another approach after looking at your example.
A global registry holds a mapping between function name (an std::string) and run time (an std::size_t representing the number of milliseconds).
An AutoProfiler is constructed providing the name of the function, and it will record the current time. Upon destruction (which will happen as we exit the function) it will calculate the elapsed time and record it in the global registry.
When the program ends we print the contents of the map (to do so we utilize the std::atexit function).
The code looks as follows:
#include <cstdlib>
#include <iostream>
#include <map>
#include <chrono>
#include <cmath>
using ProfileMapping = std::map<std::string, std::size_t>;
ProfileMapping& Map() {
static ProfileMapping map;
return map;
}
void show_profiles() {
for(const auto & pair : Map()) {
std::cout << pair.first << " : " << pair.second << std::endl;
}
}
class AutoProfiler {
public:
AutoProfiler(std::string name)
: m_name(std::move(name)),
m_beg(std::chrono::high_resolution_clock::now()) { }
~AutoProfiler() {
auto end = std::chrono::high_resolution_clock::now();
auto dur = std::chrono::duration_cast<std::chrono::milliseconds>(end - m_beg);
Map().emplace(m_name, dur.count());
}
private:
std::string m_name;
std::chrono::time_point<std::chrono::high_resolution_clock> m_beg;
};
void foo() {
AutoProfiler ap("foo");
long double x {1};
for(std::size_t k = 0; k < 1000000; ++k) {
x += std::sqrt(k);
}
}
void bar() {
AutoProfiler ap("bar");
long double x {1};
for(std::size_t k = 0; k < 10000; ++k) {
x += std::sqrt(k);
}
}
void baz() {
AutoProfiler ap("baz");
long double x {1};
for(std::size_t k = 0; k < 100000000; ++k) {
x += std::sqrt(k);
}
}
int main() {
std::atexit(show_profiles);
foo();
bar();
baz();
}
I compiled it as:
$ g++ AutoProfile.cpp -std=c++14 -Wall -Wextra
and obtained:
$ ./a.out
bar : 0
baz : 738
foo : 7
You do not need -std=c++14, but you will need at least -std=c++11.
I realize this is not what you are looking for, but I liked your question and decided to pitch in my $0.02.
And notice that if you use the following definition:
using ProfileMapping = std::multi_map<std::string, std::size_t>;
you can record every access to each function (instead of ditching the new results once the first entry has been written, or overwriting the old results).
You could do something similar to the following. It's a bit awkward, but may do what you want a little more directly than mapping to an integer:
#include <iostream>
template <const char *name>
class Profile{
public:
Profile() {
std::cout << "start: " << name << std::endl;
}
~Profile() {
std::cout << "stop: " << name << std::endl;
}
};
constexpr const char myFunction1Name[] = "myFunction1";
void myFunction1(){
Profile<myFunction1Name> profile_me;
/* some computations here */
}
int main()
{
myFunction1();
}

How to make a less than comparison in template meta-programming?

I had this question asked of me on Monday and for the life of me I don't know how to answer. Since I don't know, I now want to very much find out. Curiosity is killing this cat. Given two integers, return the lesser at compile time.
template<int M, int N>
struct SmallerOfMandN{
//and magic happenes here
};
Got pointers or how to do it? (Will start reading Boost MPL tonight.)
That is called the minimum of two numbers, and you don't need world heavy weight library like mpl to do such a thing:
template <int M, int N>
struct compile_time_min
{
static const int smaller = M < N ? M : N;
};
int main()
{
const int smaller = compile_time_min<10, 5>::smaller;
}
Of course if it was C++0x you could easily say:
constexpr int compile_time_min(int M, int N)
{
return M < N ? M : N;
}
int main()
{
constexpr int smaller = compile_time_min(10, 5);
}