Excuse the title but I lack the terminology for conveying what I mean.
I am creating a class that will store data parsed at compile-time from a string, however, it's members templates are dependant on the number of "words" found on that string. I came up with a solution that uses a separate function for computing the number of words on a given string, and then I use a macro CREATE_PATTERN to pass the returned value to instantiate the class I mentioned before while also passing the string to the class constructor since it will need it.
Here's my code as it stands:
template <size_t N>
class Pattern
{
std::array<unsigned char, N> m_pattern{};
std::bitset<N> m_mask{};
public:
constexpr Pattern(std::string_view pattern)
{
// do some logic with pattern
}
// for testing
size_t getWordCount()
{
return N;
}
};
// count 'words' in a string and return result
constexpr size_t wordCount(std::string_view pattern)
{
size_t count{ 0 };
bool lastWS{ true };
for (const char c : pattern)
{
if (c == ' ')
lastWS = true;
else
{
if (lastWS)
++count;
lastWS = false;
}
}
return count;
}
// macro for instantiating templated pattern with counted words, also passing pattern string to pattern constructor
#define CREATE_PATTERN(STR) Pattern<wordCount(STR)>(STR)
// I want to create my patterns in this nice one-liner fashion
auto pattern_a = CREATE_PATTERN(" ? AA BB CC DD EE ");
auto pattern_b = CREATE_PATTERN(" ? AA BB CC DD EE ");
auto pattern_c = CREATE_PATTERN(" ? AA BB CC DD EE ");
// etc...
int main()
{
std::cout << pattern_a.getWordCount(); // correctly returns 6
return 0;
}
This works and doesn't look too bad to me, however, I believe there may be a better solution for this problem, especially since preprocessor macro uses are usually avoided and replaceable for constexpr a lot of the time.