Skip to content

Conversation

@futuarmo
Copy link
Contributor

Fixes #1466
using is_always_equal = true_type; presents in _Default_allocator_traits, so according to this part of LWG:

Add a new subclause in Annex D after D.13 [depr.str.strstreams]:
D.? The default allocator [depr.default.allocator]

-?- The following member is defined in addition to those specified in 20.10.10 [default.allocator]:

namespace std {
  template <class T> class allocator {
  public:
    using is_always_equal = true_type;
  };
}

I've just marked is_always_equal member of std::allocator<T> as deprecated

@futuarmo futuarmo requested a review from a team as a code owner November 24, 2020 15:06
@StephanTLavavej StephanTLavavej added the LWG Library Working Group issue label Nov 25, 2020
@StephanTLavavej
Copy link
Member

Thanks for implementing this LWG issue resolution! 😺

I pushed a small change for consistency, although it wasn't a correctness issue. We have machinery (used by allocator_traits via _Normal_allocator_traits) that inspects user-defined allocators to detect whether they provide pointer etc. typedefs and member functions. Because it's possible for user-defined allocators to derive from std::allocator, it would be undesirable if this detection machinery warned about using the old std::allocator members, when they weren't being directly mentioned by the user. Therefore, we suppress the deprecation warnings around the detection machinery. I added such suppression around _Get_is_always_equal for consistency. This wasn't actually leading to any warnings, because we also have suppression around _Normal_allocator_traits:

STL/stl/inc/xmemory

Lines 495 to 512 in 19c683d

_STL_DISABLE_DEPRECATED_WARNING
template <class _Alloc>
struct _Normal_allocator_traits { // defines traits for allocators
using allocator_type = _Alloc;
using value_type = typename _Alloc::value_type;
using pointer = typename _Get_pointer_type<_Alloc>::type;
using const_pointer = typename _Get_const_pointer_type<_Alloc>::type;
using void_pointer = typename _Get_void_pointer_type<_Alloc>::type;
using const_void_pointer = typename _Get_const_void_pointer_type<_Alloc>::type;
using size_type = typename _Get_size_type<_Alloc>::type;
using difference_type = typename _Get_difference_type<_Alloc>::type;
using propagate_on_container_copy_assignment = typename _Get_propagate_on_container_copy<_Alloc>::type;
using propagate_on_container_move_assignment = typename _Get_propagate_on_container_move<_Alloc>::type;
using propagate_on_container_swap = typename _Get_propagate_on_container_swap<_Alloc>::type;
using is_always_equal = typename _Get_is_always_equal<_Alloc>::type;

Although nothing else in the STL uses _Get_is_always_equal, it seemed best to be consistent here.

I manually tested this with:

#include <memory>
#include <type_traits>
using namespace std;

template <typename T>
struct UserAlloc : allocator<T> {
    UserAlloc()                 = default;
    UserAlloc(const UserAlloc&) = default;
    template <typename U>
    UserAlloc(const UserAlloc<U>&) {}

    template <typename U>
    struct rebind {
        using other = UserAlloc<U>;
    };
};

int main() {
#ifdef ACCESS_DIRECTLY
    static_assert(is_same_v<UserAlloc<int>::is_always_equal, true_type>);
#endif

    static_assert(is_same_v<allocator_traits<UserAlloc<int>>::is_always_equal, true_type>);
}

Finally, as an exception to our using convention, we used typedef when deprecating, due to an EDG bug that was fixed long ago. I think that's no longer a problem (and the tests are passing), so applying the attribute to using here is reasonable. If this causes problems for our ancient CUDA 9.2 coverage in our internal test harness, I'll push a change, but let's see if it works.

@StephanTLavavej

This comment has been minimized.

@azure-pipelines

This comment has been minimized.

@CaseyCarter CaseyCarter self-assigned this Nov 30, 2020
@CaseyCarter CaseyCarter removed their assignment Nov 30, 2020
@StephanTLavavej StephanTLavavej self-assigned this Dec 1, 2020
@StephanTLavavej StephanTLavavej merged commit 6fe20e6 into microsoft:master Dec 1, 2020
@StephanTLavavej
Copy link
Member

Thanks for implementing another LWG issue resolution and encouraging users to modernize their code! 🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

LWG Library Working Group issue

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LWG-3170 is_always_equal added to std::allocator makes the standard library treat derived types as always equal

3 participants