I'm writing a C++ library with high-performance operations on integers.
One of the functions will be integer factorization.
Now, I stumbled on the problem, what should the API for the function be?
32-bit unsigned integers can have up to 10 different prime factors.
64-bit unsigned integers can have up to 16 different prime factors.
There can be only one prime factor >= sqrt(number)
The easiest solution would be to just return a std::vector of pairs {prime, power} - but I don't want to perform any allocations. I don't want to depend on any external library.
Also, I want the function to be constexpr, and C++14 standard library limitations disallow usage of std::array here.
But that leads to a problem - the sizeof of the returned value will be pretty large, and even with RVO (return value optimization) it seems not ideal.
What API should this function have? A C-like one, when user provides an output buffer / output iterator ? Returning some class that has the values compressed, and provides a forward iterator to go through them?
Or am I overthinking things, and should just return a struct-wrapped array with all the pairs prime-power and don't care about the size?
This question is opinion-based, so there is no a good or bad answer, but I'd like to hear some opinions about it before deciding.
What I have tried:
For uint32_t, the simplest solution:
struct FactorU32 {
uint32_t prime;
uint32_t power;
};
class FactorizationU32 {
FactorU32 factors[10];
size_t count;
};
FactorizationU32 factorize(uint32_t n);
For uint64_t, the simplest solution:
struct FactorU64 {
uint64_t prime;
uint64_t power;
};
class FactorizationU64 {
FactorU64 factors[16];
size_t count;
};
FactorizationU64 factorize(uint64_t n);
One of the technics that would reduce return value size, but would require custom iterators for accessing:
class FactorizationU32 {
uint16_t primes[10];
uint8_t powers[10];
size_t count;
};
(and equivalent for uint64_t)