I'm in a situation where I want to create a constexpr std::array
with "variable length". As an example, say I have some constexpr predicate f
, I have a constexpr array a
, and want to create the filtered array b
that contains the elements of a
satisfying the predicate f
. Now, I have already found a bad solution to this problem:
#include <array>
constexpr bool f(int a)
{
return a % 2 == 0; // Just an example, could be anything
}
template <auto a>
constexpr auto filter()
{
constexpr auto size = []{
int result = 0;
for (int i : a) {
if (f(i)) ++result;
}
return result;
}();
auto result = std::array<int, size>();
int index = 0;
for (int i : a) {
if (f(i)) {
result[index] = i;
++index;
}
}
return result;
}
int main()
{
constexpr auto a1 = std::array{1, 2, 3};
constexpr auto a2 = std::array{2, 3, 4};
constexpr auto b1 = filter<a1>();
constexpr auto b2 = filter<a2>();
static_assert(b1 == std::array{2});
static_assert(b2 == std::array{2, 4});
}
The issue with this solution is that I have to do the whole calculation twice: once to determine the size of the array, and the second time to populate the array. So my question is: is there any way to do this without having to do the calculations twice like this? Note that in reality I want to be able to do this with more than just filters, so I would rather not have solutions that are particular to just filters. The general idea is creating constexpr std::array
s where the size isn't really known until the computation is done.
I have tried using a constexpr std::vector
, but the issue there is that I can't find any way to get the values from it in a constexpr-friendly way.
I'm using GCC 13, so any feature implemented in it is fair game for me.