0

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::arrays 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.

sudgy
  • 491
  • 1
  • 3
  • 15
  • Yep, don't know how I didn't find that in all the searching I did. I'll see if I can figure out how to close this. – sudgy Jun 29 '23 at 02:41

0 Answers0