I created the following constexpr function:
template <unsigned int M, unsigned int N, unsigned int P, typename T, T... ints>
constexpr int computeGeneratorCount(std::integer_sequence<T, ints...> int_seq)
{
int count = 0;
(([count] {
int i = ints / N / P;
int j = (ints - i * N * P) / P;
int k = (ints - i * N * P - j * P);
Plane pl = Plane(i, j, k);
if (pl.containsPoint(0, 0))
count++;
}(), ...);
return count;
}
Now I am trying to call this function like this:
static constexpr int generatorCount = computeGeneratorCount<11, 11, 4, std::size_t>(std::make_index_sequence<11 * 11 * 4>{});
but I am getting multiple compilation errors.
The class Plane is as follows:
class Plane
{
private:
int m_orient;
int m_row, m_col;
public:
constexpr Plane(int row, int col, int orient) : m_row(row), m_col(col), m_orient(orient) {}
bool containsPoint(int x, int y) const {
return true;
}
}
The function containsPoint is in reality more complex but I am only giving here a minimum reproducible example.
I am only now learning compile time computations. Can anyone give me a hint in the right direction?
Thank you!
If you begin with compile time computations, I would suggest to begin with the easy way, i.e. use the fact that you can do compile time computations almost as "ordinary" code. For instance, you could have
template <unsigned int M, unsigned int N, unsigned int P>
constexpr int computeGeneratorCount () {
std::size_t T = M*N*P;
int count = 0;
for (std::size_t t=0; t<T; t++) {
int i = t / N / P;
int j = (t - i * N * P) / P;
int k = (t - i * N * P - j * P);
Plane pl {i, j, k};
if (pl.containsPoint(0, 0)) {
count++;
}
}
return count;
}
You can observe here that one can use regular for loops, without the need to use fold expressions and std::index_sequence for instance. Note that it requires that Plane::containsPoint becomes constexpr (which might be a no go in your case).
Demo
OTOH, it is still important to know about fold expressions and al. but it tends to make the code less readable if you’re not used to it.
If you want to keep an approach with fold expression, you might define an intermediate lambda:
auto fct = [&count] (auto w) {
int i = w / N / P;
int j = (w- i * N * P) / P;
int k = (w- i * N * P - j * P);
Plane pl = Plane {i, j, k};
if (pl.containsPoint(0, 0))
count++;
};
which makes computeGeneratorCount easier to write:
template <unsigned int M, unsigned int N, unsigned int P, typename T, T... ints>
constexpr int computeGeneratorCount(std::integer_sequence<T, ints...>) {
int count = 0;
auto fct = [&count] (auto w) {
int i = w / N / P;
int j = (w- i * N * P) / P;
int k = (w- i * N * P - j * P);
Plane pl = Plane {i, j, k};
if (pl.containsPoint(0, 0))
count++;
};
(fct(ints), ...);
return count;
}
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With