Imagine you'd write an own container-class. And you'd put some C 20 constaints on the allocator. Is there a concept which tests for alle the parts of a std::allocator<>-conformant class ?
CodePudding user response:
There are no such concepts in the standard, but you can compose one yourself, for example like this (based on boost proposal tickcpp):
#include <concepts>
#include <iterator>
template <class P>
concept nullable_pointer = std::regular<P> &&
std::constructible_from<P, std::nullptr_t> &&
std::equality_comparable_with<P, std::nullptr_t>;
template<class A>
concept allocator = std::copy_constructible<A> &&
std::equality_comparable<A> &&
requires (A& a) {
{ a.allocate(0) } -> nullable_pointer;
{ a.allocate(0) } -> std::random_access_iterator;
{ *a.allocate(0) } -> std::same_as<typename A::value_type&>;
};
CodePudding user response:
Ok, there is no trait or concept that fits. So I wrote my own concept that adheres to the parts an allocator needs according to C 20:
template<typename Alloc, typename T = typename std::allocator_traits<Alloc>::value_type>
concept allocator_concept =
requires( typename Alloc::size_type size )
{
{ size } -> std::convertible_to<std::size_t>;
}
&&
requires( typename Alloc::value_type value )
{
{ value } -> std::convertible_to<T>;
}
&&
requires()
{
{ Alloc() } noexcept;
}
&&
requires( Alloc const &b )
{
{ Alloc( b ) } noexcept;
}
&&
requires( Alloc a, std::size_t n )
{
{ a.allocate( n ) } -> std::convertible_to<T *>;
}
&&
requires( Alloc a, T *p, std::size_t n )
{
{ a.deallocate( p, n ) };
};
BTW: Can anyone tell me why deallocate isn't noexcept (at least to en.cppreference.com) ?