There is no such is_allocator
trait in the Standard Library, but you can write one yourself:
#include <vector>
#include <utility>
template <class T>
class is_allocator
{
typedef char yes;
typedef long no;
// you can extend this with many more checks on the allocator interface
template <class C> static yes check( decltype(std::declval<C>().allocate(0)) );
template <class C> static no check(...);
public:
enum { value = sizeof(check<T>(0)) == sizeof(yes) };
};
int main()
{
std::vector<int> v { 1, 2 };
using V = decltype(v)::value_type;
using A = decltype(v)::allocator_type;
static_assert(!is_allocator<V>::value, "");
static_assert( is_allocator<A>::value, "");
}
The above code checks whether a type has a member function allocate(size_type)
by calling that function inside a decltype()
expression. If such a function exists, the check<T>(0)
will select that overload in the enum
expression and the value
will become true
. As a check, you can static_assert
this on the template parameters of a std::vector
.
Obviously, you could improve this approach by having a bunch of fine-grained traits has_allocate
, has_deallocate
and all the other essential member function that make up the entire Allocator requirements in the Standard. Once you have done that, you can define is_allocator
as the logical and over all these fine-grained traits.