forked from OSchip/llvm-project
[libcxx][NFC] Make sequence containers slightly more SFINAE-friendly during CTAD.
Disable the constructors taking `(size_type, const value_type&, allocator_type)` if `allocator_type` is not a valid allocator. Otherwise, these constructors are considered when resolving e.g. `(int*, int*, NotAnAllocator())`, leading to a hard error during instantiation. A hard error makes the Standard's requirement to not consider deduction guides of the form `(Iterator, Iterator, BadAllocator)` during overload resolution essentially non-functional. The previous approach was to SFINAE away `allocator_traits`. This patch SFINAEs away the specific constructors instead, for consistency with `basic_string` -- see [LWG3076](wg21.link/lwg3076) which describes a very similar problem for strings (note, however, that unlike LWG3076, no valid constructor call is affected by the bad instantiation). Differential Revision: https://reviews.llvm.org/D114311
This commit is contained in:
parent
9e647806f3
commit
7da4ee6f23
|
@ -349,14 +349,6 @@ struct _LIBCPP_TEMPLATE_VIS allocator_traits
|
|||
}
|
||||
};
|
||||
|
||||
// A version of `allocator_traits` for internal usage that SFINAEs away if the
|
||||
// given allocator doesn't have a nested `value_type`. This helps avoid hard
|
||||
// errors when forming implicit deduction guides for a container that has an
|
||||
// invalid Allocator type. See https://wg21.link/LWGXXXXX.
|
||||
// TODO(varconst): use the actual link once available.
|
||||
template <class _Alloc, class _ValueType = typename _Alloc::value_type>
|
||||
struct _LIBCPP_TEMPLATE_VIS __allocator_traits : allocator_traits<_Alloc> {};
|
||||
|
||||
template <class _Traits, class _Tp>
|
||||
struct __rebind_alloc_helper {
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
|
|
|
@ -915,16 +915,16 @@ class __deque_base
|
|||
__deque_base(const __deque_base& __c);
|
||||
__deque_base& operator=(const __deque_base& __c);
|
||||
public:
|
||||
typedef _Allocator allocator_type;
|
||||
typedef allocator_traits<allocator_type> __alloc_traits;
|
||||
typedef typename __alloc_traits::size_type size_type;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef allocator_traits<allocator_type> __alloc_traits;
|
||||
typedef typename __alloc_traits::size_type size_type;
|
||||
|
||||
typedef _Tp value_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename __alloc_traits::difference_type difference_type;
|
||||
typedef typename __alloc_traits::pointer pointer;
|
||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||
typedef _Tp value_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename __alloc_traits::difference_type difference_type;
|
||||
typedef typename __alloc_traits::pointer pointer;
|
||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||
|
||||
static const difference_type __block_size;
|
||||
|
||||
|
@ -1259,20 +1259,20 @@ public:
|
|||
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
|
||||
"Allocator::value_type must be same type as value_type");
|
||||
|
||||
typedef __deque_base<value_type, allocator_type> __base;
|
||||
typedef __deque_base<value_type, allocator_type> __base;
|
||||
|
||||
typedef typename __base::__alloc_traits __alloc_traits;
|
||||
typedef typename __base::reference reference;
|
||||
typedef typename __base::const_reference const_reference;
|
||||
typedef typename __base::iterator iterator;
|
||||
typedef typename __base::const_iterator const_iterator;
|
||||
typedef typename __allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename __base::difference_type difference_type;
|
||||
typedef typename __base::__alloc_traits __alloc_traits;
|
||||
typedef typename __base::reference reference;
|
||||
typedef typename __base::const_reference const_reference;
|
||||
typedef typename __base::iterator iterator;
|
||||
typedef typename __base::const_iterator const_iterator;
|
||||
typedef typename __base::size_type size_type;
|
||||
typedef typename __base::difference_type difference_type;
|
||||
|
||||
typedef typename __base::pointer pointer;
|
||||
typedef typename __base::const_pointer const_pointer;
|
||||
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef typename __base::pointer pointer;
|
||||
typedef typename __base::const_pointer const_pointer;
|
||||
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
using typename __base::__deque_range;
|
||||
using typename __base::__deque_block_range;
|
||||
|
@ -1289,7 +1289,14 @@ public:
|
|||
explicit deque(size_type __n, const _Allocator& __a);
|
||||
#endif
|
||||
deque(size_type __n, const value_type& __v);
|
||||
deque(size_type __n, const value_type& __v, const allocator_type& __a);
|
||||
|
||||
template <class = __enable_if_t<__is_allocator<_Allocator>::value> >
|
||||
deque(size_type __n, const value_type& __v, const allocator_type& __a) : __base(__a)
|
||||
{
|
||||
if (__n > 0)
|
||||
__append(__n, __v);
|
||||
}
|
||||
|
||||
template <class _InputIter>
|
||||
deque(_InputIter __f, _InputIter __l,
|
||||
typename enable_if<__is_cpp17_input_iterator<_InputIter>::value>::type* = 0);
|
||||
|
@ -1608,14 +1615,6 @@ deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v)
|
|||
__append(__n, __v);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
deque<_Tp, _Allocator>::deque(size_type __n, const value_type& __v, const allocator_type& __a)
|
||||
: __base(__a)
|
||||
{
|
||||
if (__n > 0)
|
||||
__append(__n, __v);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
template <class _InputIter>
|
||||
deque<_Tp, _Allocator>::deque(_InputIter __f, _InputIter __l,
|
||||
|
|
|
@ -186,6 +186,7 @@ template <class T, class Allocator, class Predicate>
|
|||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <version>
|
||||
|
||||
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
|
||||
|
@ -643,12 +644,12 @@ public:
|
|||
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
|
||||
"Allocator::value_type must be same type as value_type");
|
||||
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
|
||||
typedef typename __allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename allocator_traits<allocator_type>::pointer pointer;
|
||||
typedef typename allocator_traits<allocator_type>::const_pointer const_pointer;
|
||||
typedef typename allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename allocator_traits<allocator_type>::difference_type difference_type;
|
||||
|
||||
typedef typename base::iterator iterator;
|
||||
typedef typename base::const_iterator const_iterator;
|
||||
|
@ -669,7 +670,13 @@ public:
|
|||
explicit forward_list(size_type __n, const allocator_type& __a);
|
||||
#endif
|
||||
forward_list(size_type __n, const value_type& __v);
|
||||
forward_list(size_type __n, const value_type& __v, const allocator_type& __a);
|
||||
|
||||
template <class = __enable_if_t<__is_allocator<_Alloc>::value> >
|
||||
forward_list(size_type __n, const value_type& __v, const allocator_type& __a) : base(__a)
|
||||
{
|
||||
insert_after(cbefore_begin(), __n, __v);
|
||||
}
|
||||
|
||||
template <class _InputIterator>
|
||||
forward_list(_InputIterator __f, _InputIterator __l,
|
||||
typename enable_if<
|
||||
|
@ -943,14 +950,6 @@ forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v)
|
|||
insert_after(cbefore_begin(), __n, __v);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
forward_list<_Tp, _Alloc>::forward_list(size_type __n, const value_type& __v,
|
||||
const allocator_type& __a)
|
||||
: base(__a)
|
||||
{
|
||||
insert_after(cbefore_begin(), __n, __v);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
template <class _InputIterator>
|
||||
forward_list<_Tp, _Alloc>::forward_list(_InputIterator __f, _InputIterator __l,
|
||||
|
|
|
@ -845,24 +845,24 @@ class _LIBCPP_TEMPLATE_VIS list
|
|||
typedef typename base::__link_pointer __link_pointer;
|
||||
|
||||
public:
|
||||
typedef _Tp value_type;
|
||||
typedef _Alloc allocator_type;
|
||||
typedef _Tp value_type;
|
||||
typedef _Alloc allocator_type;
|
||||
static_assert((is_same<value_type, typename allocator_type::value_type>::value),
|
||||
"Invalid allocator::value_type");
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::const_pointer const_pointer;
|
||||
typedef typename __allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::iterator iterator;
|
||||
typedef typename base::const_iterator const_iterator;
|
||||
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::const_pointer const_pointer;
|
||||
typedef typename base::size_type size_type;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::iterator iterator;
|
||||
typedef typename base::const_iterator const_iterator;
|
||||
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
#if _LIBCPP_STD_VER > 17
|
||||
typedef size_type __remove_return_type;
|
||||
typedef size_type __remove_return_type;
|
||||
#else
|
||||
typedef void __remove_return_type;
|
||||
typedef void __remove_return_type;
|
||||
#endif
|
||||
|
||||
_LIBCPP_INLINE_VISIBILITY
|
||||
|
@ -885,7 +885,16 @@ public:
|
|||
explicit list(size_type __n, const allocator_type& __a);
|
||||
#endif
|
||||
list(size_type __n, const value_type& __x);
|
||||
list(size_type __n, const value_type& __x, const allocator_type& __a);
|
||||
template <class = __enable_if_t<__is_allocator<_Alloc>::value> >
|
||||
list(size_type __n, const value_type& __x, const allocator_type& __a) : base(__a)
|
||||
{
|
||||
#if _LIBCPP_DEBUG_LEVEL == 2
|
||||
__get_db()->__insert_c(this);
|
||||
#endif
|
||||
for (; __n > 0; --__n)
|
||||
push_back(__x);
|
||||
}
|
||||
|
||||
template <class _InpIter>
|
||||
list(_InpIter __f, _InpIter __l,
|
||||
typename enable_if<__is_cpp17_input_iterator<_InpIter>::value>::type* = 0);
|
||||
|
@ -1241,17 +1250,6 @@ list<_Tp, _Alloc>::list(size_type __n, const value_type& __x)
|
|||
push_back(__x);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
list<_Tp, _Alloc>::list(size_type __n, const value_type& __x, const allocator_type& __a)
|
||||
: base(__a)
|
||||
{
|
||||
#if _LIBCPP_DEBUG_LEVEL == 2
|
||||
__get_db()->__insert_c(this);
|
||||
#endif
|
||||
for (; __n > 0; --__n)
|
||||
push_back(__x);
|
||||
}
|
||||
|
||||
template <class _Tp, class _Alloc>
|
||||
template <class _InpIter>
|
||||
list<_Tp, _Alloc>::list(_InpIter __f, _InpIter __l,
|
||||
|
|
|
@ -350,23 +350,23 @@ class _LIBCPP_TEMPLATE_VIS vector
|
|||
: private __vector_base<_Tp, _Allocator>
|
||||
{
|
||||
private:
|
||||
typedef __vector_base<_Tp, _Allocator> __base;
|
||||
typedef allocator<_Tp> __default_allocator_type;
|
||||
typedef __vector_base<_Tp, _Allocator> __base;
|
||||
typedef allocator<_Tp> __default_allocator_type;
|
||||
public:
|
||||
typedef vector __self;
|
||||
typedef _Tp value_type;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef allocator_traits<allocator_type> __alloc_traits;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename __allocator_traits<allocator_type>::size_type size_type;
|
||||
typedef typename __alloc_traits::difference_type difference_type;
|
||||
typedef typename __alloc_traits::pointer pointer;
|
||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||
typedef __wrap_iter<pointer> iterator;
|
||||
typedef __wrap_iter<const_pointer> const_iterator;
|
||||
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
typedef vector __self;
|
||||
typedef _Tp value_type;
|
||||
typedef _Allocator allocator_type;
|
||||
typedef allocator_traits<allocator_type> __alloc_traits;
|
||||
typedef value_type& reference;
|
||||
typedef const value_type& const_reference;
|
||||
typedef typename __alloc_traits::size_type size_type;
|
||||
typedef typename __alloc_traits::difference_type difference_type;
|
||||
typedef typename __alloc_traits::pointer pointer;
|
||||
typedef typename __alloc_traits::const_pointer const_pointer;
|
||||
typedef __wrap_iter<pointer> iterator;
|
||||
typedef __wrap_iter<const_pointer> const_iterator;
|
||||
typedef _VSTD::reverse_iterator<iterator> reverse_iterator;
|
||||
typedef _VSTD::reverse_iterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
static_assert((is_same<typename allocator_type::value_type, value_type>::value),
|
||||
"Allocator::value_type must be same type as value_type");
|
||||
|
@ -395,7 +395,21 @@ public:
|
|||
explicit vector(size_type __n, const allocator_type& __a);
|
||||
#endif
|
||||
vector(size_type __n, const value_type& __x);
|
||||
vector(size_type __n, const value_type& __x, const allocator_type& __a);
|
||||
|
||||
template <class = __enable_if_t<__is_allocator<_Allocator>::value> >
|
||||
vector(size_type __n, const value_type& __x, const allocator_type& __a)
|
||||
: __base(__a)
|
||||
{
|
||||
#if _LIBCPP_DEBUG_LEVEL == 2
|
||||
__get_db()->__insert_c(this);
|
||||
#endif
|
||||
if (__n > 0)
|
||||
{
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n, __x);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _InputIterator>
|
||||
vector(_InputIterator __first,
|
||||
typename enable_if<__is_cpp17_input_iterator <_InputIterator>::value &&
|
||||
|
@ -1126,20 +1140,6 @@ vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x)
|
|||
}
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
vector<_Tp, _Allocator>::vector(size_type __n, const value_type& __x, const allocator_type& __a)
|
||||
: __base(__a)
|
||||
{
|
||||
#if _LIBCPP_DEBUG_LEVEL == 2
|
||||
__get_db()->__insert_c(this);
|
||||
#endif
|
||||
if (__n > 0)
|
||||
{
|
||||
__vallocate(__n);
|
||||
__construct_at_end(__n, __x);
|
||||
}
|
||||
}
|
||||
|
||||
template <class _Tp, class _Allocator>
|
||||
template <class _InputIterator>
|
||||
vector<_Tp, _Allocator>::vector(_InputIterator __first,
|
||||
|
|
|
@ -27,6 +27,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -25,6 +25,7 @@ struct some_alloc
|
|||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
~some_alloc() noexcept(false);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -29,6 +29,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -27,6 +27,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -34,6 +34,7 @@ struct some_alloc
|
|||
|
||||
some_alloc() {}
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::true_type propagate_on_container_swap;
|
||||
|
@ -46,6 +47,7 @@ struct some_alloc2
|
|||
|
||||
some_alloc2() {}
|
||||
some_alloc2(const some_alloc2&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::false_type propagate_on_container_swap;
|
||||
|
|
|
@ -27,6 +27,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -25,6 +25,7 @@ struct some_alloc
|
|||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
~some_alloc() noexcept(false);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -29,6 +29,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -27,6 +27,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -35,6 +35,7 @@ struct some_alloc
|
|||
|
||||
some_alloc() {}
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::true_type propagate_on_container_swap;
|
||||
|
@ -47,6 +48,7 @@ struct some_alloc2
|
|||
|
||||
some_alloc2() {}
|
||||
some_alloc2(const some_alloc2&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::false_type propagate_on_container_swap;
|
||||
|
|
|
@ -27,6 +27,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -25,6 +25,7 @@ struct some_alloc
|
|||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
~some_alloc() noexcept(false);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -29,6 +29,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -27,6 +27,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -34,6 +34,7 @@ struct some_alloc
|
|||
|
||||
some_alloc() {}
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::true_type propagate_on_container_swap;
|
||||
|
@ -46,6 +47,7 @@ struct some_alloc2
|
|||
|
||||
some_alloc2() {}
|
||||
some_alloc2(const some_alloc2&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::false_type propagate_on_container_swap;
|
||||
|
|
|
@ -27,6 +27,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -25,6 +25,7 @@ struct some_alloc
|
|||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
~some_alloc() noexcept(false);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -29,6 +29,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
@ -38,6 +39,7 @@ struct some_alloc2
|
|||
|
||||
some_alloc2() {}
|
||||
some_alloc2(const some_alloc2&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::false_type propagate_on_container_move_assignment;
|
||||
|
@ -51,6 +53,7 @@ struct some_alloc3
|
|||
|
||||
some_alloc3() {}
|
||||
some_alloc3(const some_alloc3&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::false_type propagate_on_container_move_assignment;
|
||||
|
|
|
@ -27,6 +27,7 @@ struct some_alloc
|
|||
{
|
||||
typedef T value_type;
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
};
|
||||
|
||||
int main(int, char**)
|
||||
|
|
|
@ -35,6 +35,7 @@ struct some_alloc
|
|||
|
||||
some_alloc() {}
|
||||
some_alloc(const some_alloc&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::true_type propagate_on_container_swap;
|
||||
|
@ -47,6 +48,7 @@ struct some_alloc2
|
|||
|
||||
some_alloc2() {}
|
||||
some_alloc2(const some_alloc2&);
|
||||
void allocate(size_t);
|
||||
void deallocate(void*, unsigned) {}
|
||||
|
||||
typedef std::false_type propagate_on_container_swap;
|
||||
|
|
Loading…
Reference in New Issue