Commit 72cd787e authored by Eric Fiselier's avatar Eric Fiselier
Browse files

Merge R292276: Fix std::string assignment ambiguity from braced initializer lists.

When support for `basic_string_view` was added to string it also
added new assignment operators from `basic_string_view`. These caused
ambiguity when assigning from a braced initializer. This patch fixes
that regression by making the basic_string_view assignment operator
rank lower in overload resolution by making it a template.

llvm-svn: 292354
parent 5476b86e
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -818,6 +818,7 @@ public:
    operator __self_view() const _NOEXCEPT { return __self_view(data(), size()); }

    basic_string& operator=(const basic_string& __str);
    template <class = void>
    _LIBCPP_INLINE_VISIBILITY
    basic_string& operator=(__self_view __sv)  {return assign(__sv);}
#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES
+36 −0
Original line number Diff line number Diff line
//===----------------------------------------------------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

// UNSUPPORTED: c++98, c++03

// <string>

// basic_string<charT,traits,Allocator>&
//   operator=(basic_string<charT,traits,Allocator>&& str);

#include <string>
#include <cassert>

#include "test_macros.h"

int main()
{
  // Test that assignment from {} and {ptr, len} are allowed and are not
  // ambiguous.
  {
    std::string s = "hello world";
    s = {};
    assert(s.empty());
  }
  {
    std::string s = "hello world";
    s = {"abc", 2};
    assert(s == "ab");
  }
}
+22 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ test(std::basic_string_view<charT> sv)
    typedef std::basic_string<charT, std::char_traits<charT>, test_allocator<charT> > S;
    typedef typename S::traits_type T;
    typedef typename S::allocator_type A;
  {
    S s2(sv);
    LIBCPP_ASSERT(s2.__invariants());
    assert(s2.size() == sv.size());
@@ -35,6 +36,16 @@ test(std::basic_string_view<charT> sv)
    assert(s2.get_allocator() == A());
    assert(s2.capacity() >= s2.size());
  }
  {
    S s2;
    s2 = sv;
    LIBCPP_ASSERT(s2.__invariants());
    assert(s2.size() == sv.size());
    assert(T::compare(s2.data(), sv.data(), sv.size()) == 0);
    assert(s2.get_allocator() == A());
    assert(s2.capacity() >= s2.size());
  }
}

template <class charT, class A>
void
@@ -42,6 +53,7 @@ test(std::basic_string_view<charT> sv, const A& a)
{
    typedef std::basic_string<charT, std::char_traits<charT>, A> S;
    typedef typename S::traits_type T;
  {
    S s2(sv, a);
    LIBCPP_ASSERT(s2.__invariants());
    assert(s2.size() == sv.size());
@@ -49,6 +61,16 @@ test(std::basic_string_view<charT> sv, const A& a)
    assert(s2.get_allocator() == a);
    assert(s2.capacity() >= s2.size());
  }
  {
    S s2(a);
    s2 = sv;
    LIBCPP_ASSERT(s2.__invariants());
    assert(s2.size() == sv.size());
    assert(T::compare(s2.data(), sv.data(), sv.size()) == 0);
    assert(s2.get_allocator() == a);
    assert(s2.capacity() >= s2.size());
  }
}

int main()
{