I would like to define a simple template function which takes a runtime value and determines if it is a member of some set of possible values.
Usage:
int x; // <- pretend this came from elsewhere...
if (isoneof(x, {5,3,9,25}) ...
Something like:
template <typename T, size_t size>
bool isoneof(T value, T (&arr)[size])
{
for (size_t i = 0; i < size; ++i)
if (value == arr[i])
return true;
return false;
}
I assume that this is doomed to failure, as I don't see how one can create a static array inline.
I can use:
int kPossibilities[] = {5,3,9,25};
if (isoneodf(6, kPossibilities)) ...
With a minor change to isoneof:
template <typename T1, typename T2, size_t size>
bool isoneof(T1 value, const T2 (&arr)[size])
{
for (size_t i = 0; i < size; ++i)
if (value == arr[i])
return true;
return false;
}
Which also makes it a tad more flexible.
Does anyone have an improvement to offer? A better way to define a "set of static values inline"?
No, inline does not imply static not vice versa.
Static inline functions are simple. Either a function defined with the inline function specifier is inlined at a reference, or a call is made to the actual function. The compiler can choose which to do at each reference. The compiler decides if it is profitable to inline at -xO3 and above.
Static arrays are allocated memory at compile time and the memory is allocated on the stack. Whereas, the dynamic arrays are allocated memory at the runtime and the memory is allocated from heap. This is static integer array i.e. fixed memory assigned before runtime int arr[] = { 1, 3, 4 };
A variable declared inline has the same semantics as a function declared inline: it can be defined, identically, in multiple translation units, must be defined in every translation unit in which it is used, and the behavior of the program is as if there was exactly one variable.
If you like such things, then you will be a very happy user of Boost.Assign.
Boost.Assign actually proves that such semantics are possible, however one look at the source of assign will convince you that you don't want to do that by yourself :)
You will be able to create something like this however:
if (isoneof(x, list_of(2)(3)(5)(7)(11)) { ...
... the downside being you'd have to use boost::array
as the parameter instead of a built-in array (thanks, Manuel) -- however, that's a nice moment to actually start using them :>
It's possible in the next C++ standard.
Up till then, you can work around it by e.g. overloading operator,
for a static object that starts a static array.
Note: this implementation is O(n^2) and may be optimized - it's just to get the idea.
using namespace std;
template< typename T, size_t N >
struct CHead {
T values[N];
template< typename T > CHead<T,N+1> operator,( T t ) {
CHead<T,N+1> newhead;
copy( values, values+N, newhead.values);
newhead.values[N]=t;
return newhead;
}
bool contains( T t ) const {
return find( values, values+N, t ) != values+N;
}
};
struct CHeadProto {
template< typename T >
CHead<T,1> operator,( T t ) {
CHead<T,1> h = {t};
return h;
}
} head;
int main()
{
assert( (head, 1,2,3,4).contains(1) );
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With