Heh, wanted to just do a simple string match — nothing fancy even, just has to test for an exact match in a small set of strings...
There’re all kinds of ways to do this simply. But I wanted
pretty.
if (std::vector { "one", "two", "three" } --> some_string)
That is, of course, not as cool as my
<x_in_xs> stuff:
if (some_string in { "one", "two", "three" })
but x-in-xs requires a whole lot of template meta-programming and (probably) some bloat...
(I should probably test that)
But the pretty is also several hundred bytes more in size than a simple:
if (is_any_of( some_string, "one", "two", "three" ))
...which is all I need, just a couple places in the code.
Interestingly, that also compiles to the same size if I write something abominable like:
if (std::string( "one\0two\0three", 13 ).find( some_string ) != std::string::npos)
which also unfortunately returns
true
for the empty string...
“Wut? Only several hundred bytes?” you say?
Yes. My program is going to be as tiny as possible without resorting to excessive hand mico-optimizing. Just going to avoid constructs that I don’t need. (For example, I use a number of
std::unordered_map
in the code. No sense in adding several thousand bytes worth of code for a
std::unordered_set
when a map will stand-in nicely.)
Also, in case you were curious:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
// if (std::vector { "one", "two", "three" } --> some_string)
#include <algorithm>
template <typename XS>
struct container_ref
{
const XS & xs;
container_ref( const XS & xs ) : xs{xs} { }
template <typename X>
bool operator > ( const X & x ) const
{
using std::begin;
using std::end;
auto iterator = std::find( begin(xs), end(xs), x );
return iterator != end(xs);
}
};
template <typename XS>
container_ref <XS>
operator -- ( const XS & xs, int )
{
return container_ref( xs );
}
| |
1 2 3 4 5 6 7 8 9 10 11 12 13
|
// if (is_any_of( some_string, "one", "two", "three" ))
template <typename X>
bool is_any_of( const X & )
{
return false;
}
template <typename X, typename X0, typename...XS>
bool is_any_of( const X & x, const X0 & x0, XS...xs )
{
return (x == x0) or is_any_of( x, xs... );
}
| |
Sorry, not gonna post the x-in-xs stuff today. Like I said — lots of boilerplate template meta-programming.
Oh, and, C++17. Don’t give me grief about C++27.
Ever get your brain in a whirl over stupid stuff like this?