@@ -767,6 +767,33 @@ String_Traits<std::char_traits<char> >::find(const char *s,
767767
768768#define BSLSTL_CHAR_TRAITS CHAR_TRAITS
769769
770+ #endif
771+
772+ // 'MovableRef<TYPE>' is defined such that 'TYPE' cannot be deduced directly
773+ // from 'MovableRef<TYPE>' in C++11 mode. Use
774+ // 'BSLSTL_STRING_DEDUCE_RVREF(TYPE)' instead of 'MovableRef<TYPE>' in
775+ // situations where 'TYPE' must be deduced.
776+
777+ #ifdef BSLS_COMPILERFEATURES_SUPPORT_RVALUE_REFERENCES
778+ #define BSLSTL_STRING_DEDUCE_RVREF \
779+ bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> &&
780+ #define BSLSTL_STRING_DEDUCE_RVREF_1 \
781+ bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOC1> &&
782+ #define BSLSTL_STRING_DEDUCE_RVREF_2 \
783+ bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOC2> &&
784+ #else
785+ #define BSLSTL_STRING_DEDUCE_RVREF \
786+ BloombergLP::bslmf::MovableRef<bsl::basic_string<CHAR_TYPE, \
787+ CHAR_TRAITS, \
788+ ALLOCATOR> >
789+ #define BSLSTL_STRING_DEDUCE_RVREF_1 \
790+ BloombergLP::bslmf::MovableRef<bsl::basic_string<CHAR_TYPE, \
791+ CHAR_TRAITS, \
792+ ALLOC1> >
793+ #define BSLSTL_STRING_DEDUCE_RVREF_2 \
794+ BloombergLP::bslmf::MovableRef<bsl::basic_string<CHAR_TYPE, \
795+ CHAR_TRAITS, \
796+ ALLOC2> >
770797#endif
771798
772799 // =======================================
@@ -2912,34 +2939,72 @@ bool operator>=(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC>& lhs,
29122939
29132940template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
29142941basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
2915- operator +(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
2916- const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& rhs);
2942+ operator +(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
2943+ const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& rhs);
2944+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
2945+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>
2946+ operator +(BSLSTL_STRING_DEDUCE_RVREF lhs,
2947+ const basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& rhs);
2948+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
2949+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>
2950+ operator +(const basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lhs,
2951+ BSLSTL_STRING_DEDUCE_RVREF rhs);
2952+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
2953+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>
2954+ operator +(BSLSTL_STRING_DEDUCE_RVREF lhs,
2955+ BSLSTL_STRING_DEDUCE_RVREF rhs);
2956+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOC1 , class ALLOC2 >
2957+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>
2958+ operator +(const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>& lhs,
2959+ const bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>& rhs);
29172960template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOC1 , class ALLOC2 >
29182961basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>
2919- operator +(const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>& lhs,
2920- const bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>& rhs);
2962+ operator +(const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>& lhs,
2963+ BSLSTL_STRING_DEDUCE_RVREF_2 rhs);
29212964template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOC1 , class ALLOC2 >
29222965basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>
2923- operator +(const bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>& lhs,
2924- const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>& rhs);
2966+ operator +(const bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>& lhs,
2967+ const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>& rhs);
2968+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOC1 , class ALLOC2 >
2969+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>
2970+ operator +(BSLSTL_STRING_DEDUCE_RVREF_1 lhs,
2971+ const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>& rhs);
2972+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
2973+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
2974+ operator +(const CHAR_TYPE *lhs,
2975+ const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& rhs);
2976+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
2977+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>
2978+ operator +(const CHAR_TYPE *lhs,
2979+ BSLSTL_STRING_DEDUCE_RVREF rhs);
2980+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
2981+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
2982+ operator +(CHAR_TYPE lhs,
2983+ const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& rhs);
2984+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
2985+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
2986+ operator +(CHAR_TYPE lhs,
2987+ BSLSTL_STRING_DEDUCE_RVREF rhs);
29252988template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
29262989basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
2927- operator +(const CHAR_TYPE * lhs,
2928- const basic_string< CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& rhs);
2990+ operator +(const basic_string< CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
2991+ const CHAR_TYPE * rhs);
29292992template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
29302993basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
2931- operator +(CHAR_TYPE lhs,
2932- const basic_string< CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& rhs);
2994+ operator +(BSLSTL_STRING_DEDUCE_RVREF lhs,
2995+ const CHAR_TYPE * rhs);
29332996template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
29342997basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
2935- operator +(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
2936- const CHAR_TYPE * rhs);
2998+ operator +(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
2999+ CHAR_TYPE rhs);
29373000template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
29383001basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
2939- operator +(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
2940- CHAR_TYPE rhs);
3002+ operator +(BSLSTL_STRING_DEDUCE_RVREF lhs,
3003+ CHAR_TYPE rhs);
29413004 // Return the concatenation of strings constructed from the specified 'lhs'
2942- // and 'rhs' arguments, i.e., 'basic_string(lhs).append(rhs)'.
3005+ // and 'rhs' arguments, i.e., 'basic_string(lhs).append(rhs)'. The
3006+ // allocator of the returned string is determined per the rules in P1165
3007+ // (https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1165r1.html).
29433008
29443009template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
29453010std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>&
@@ -6753,37 +6818,97 @@ bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
67536818bsl::operator +(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
67546819 const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& rhs)
67556820{
6756- basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result;
6821+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR> result (
6822+ bsl::allocator_traits<ALLOCATOR>::
6823+ select_on_container_copy_construction (lhs.get_allocator ()));
67576824 result.reserve (lhs.length () + rhs.length ());
67586825 result += lhs;
67596826 result += rhs;
67606827 return result;
67616828}
67626829
6830+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
6831+ bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>
6832+ bsl::operator +(BSLSTL_STRING_DEDUCE_RVREF lhs,
6833+ const basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& rhs)
6834+ {
6835+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lvalue = lhs;
6836+ lvalue.append (rhs);
6837+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>(
6838+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
6839+ }
6840+
6841+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
6842+ bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>
6843+ bsl::operator +(const basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lhs,
6844+ BSLSTL_STRING_DEDUCE_RVREF rhs)
6845+ {
6846+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lvalue = rhs;
6847+ lvalue.insert (0 , lhs);
6848+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>(
6849+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
6850+ }
6851+
6852+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
6853+ bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>
6854+ bsl::operator +(BSLSTL_STRING_DEDUCE_RVREF lhs, BSLSTL_STRING_DEDUCE_RVREF rhs)
6855+ {
6856+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lvalue = lhs;
6857+ lvalue.append (rhs);
6858+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>(
6859+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
6860+ }
6861+
67636862template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOC1 , class ALLOC2 >
67646863bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>
67656864bsl::operator +(const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>& lhs,
67666865 const bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>& rhs)
67676866{
6768- bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2> result;
6867+ bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2> result (
6868+ bsl::allocator_traits<ALLOC2>::
6869+ select_on_container_copy_construction (rhs.get_allocator ()));
67696870 result.reserve (lhs.length () + rhs.length ());
67706871 result.append (lhs.c_str (), lhs.length ());
67716872 result += rhs;
67726873 return result;
67736874}
67746875
6876+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOC1 , class ALLOC2 >
6877+ bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOC2>
6878+ bsl::operator +(const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>& lhs,
6879+ BSLSTL_STRING_DEDUCE_RVREF_2 rhs)
6880+ {
6881+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOC2>& lvalue = rhs;
6882+ lvalue.insert (0 , lhs.c_str (), lhs.size ());
6883+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOC2>(
6884+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
6885+ }
6886+
67756887template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOC1 , class ALLOC2 >
67766888bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>
67776889bsl::operator +(const bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1>& lhs,
67786890 const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>& rhs)
67796891{
6780- bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1> result;
6892+ bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC1> result (
6893+ bsl::allocator_traits<ALLOC1>::
6894+ select_on_container_copy_construction (lhs.get_allocator ()));
67816895 result.reserve (lhs.length () + rhs.length ());
67826896 result += lhs;
67836897 result.append (rhs.c_str (), rhs.length ());
67846898 return result;
67856899}
67866900
6901+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOC1 , class ALLOC2 >
6902+ bsl::basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOC1>
6903+ bsl::operator +(BSLSTL_STRING_DEDUCE_RVREF_1 lhs,
6904+ const std::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOC2>& rhs)
6905+ {
6906+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOC1>& lvalue = lhs;
6907+ lvalue.append (rhs.c_str (), rhs.length ());
6908+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOC1>(
6909+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
6910+ }
6911+
67876912template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
67886913bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
67896914bsl::operator +(const CHAR_TYPE *lhs,
@@ -6794,54 +6919,105 @@ bsl::operator+(const CHAR_TYPE *lhs,
67946919 typename basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>::size_type
67956920 lhsLength = CHAR_TRAITS::length (lhs);
67966921
6797- basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result;
6922+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result (
6923+ bsl::allocator_traits<ALLOCATOR>::
6924+ select_on_container_copy_construction (rhs.get_allocator ()));
67986925 result.reserve (lhsLength + rhs.length ());
67996926 result.append (lhs, lhsLength);
68006927 result += rhs;
68016928 return result;
68026929}
6930+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
6931+ bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
6932+ bsl::operator +(const CHAR_TYPE *lhs, BSLSTL_STRING_DEDUCE_RVREF rhs)
6933+ {
6934+ BSLS_ASSERT_SAFE (lhs);
6935+
6936+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lvalue = rhs;
6937+ lvalue.insert (0 , lhs);
6938+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>(
6939+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
6940+ }
68036941
68046942template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
68056943bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
68066944bsl::operator +(CHAR_TYPE lhs,
68076945 const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& rhs)
68086946{
6809- basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result;
6947+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result (
6948+ bsl::allocator_traits<ALLOCATOR>::
6949+ select_on_container_copy_construction (rhs.get_allocator ()));
68106950 result.reserve (1 + rhs.length ());
68116951 result.push_back (lhs);
68126952 result += rhs;
68136953 return result;
68146954}
68156955
6956+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
6957+ bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
6958+ bsl::operator +(CHAR_TYPE lhs, BSLSTL_STRING_DEDUCE_RVREF rhs)
6959+ {
6960+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lvalue = rhs;
6961+ lvalue.insert (lvalue.begin (), lhs);
6962+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>(
6963+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
6964+ }
6965+
6966+
68166967template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
68176968bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
68186969bsl::operator +(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
68196970 const CHAR_TYPE *rhs)
68206971{
68216972 BSLS_ASSERT_SAFE (rhs);
6822-
68236973 typename basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>::size_type
68246974 rhsLength = CHAR_TRAITS::length (rhs);
68256975
6826- basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result;
6976+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result (
6977+ bsl::allocator_traits<ALLOCATOR>::
6978+ select_on_container_copy_construction (lhs.get_allocator ()));
68276979 result.reserve (lhs.length () + rhsLength);
68286980 result += lhs;
68296981 result.append (rhs, rhsLength);
68306982 return result;
68316983}
68326984
6985+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
6986+ bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
6987+ bsl::operator +(BSLSTL_STRING_DEDUCE_RVREF lhs, const CHAR_TYPE *rhs)
6988+ {
6989+ BSLS_ASSERT_SAFE (rhs);
6990+
6991+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lvalue = lhs;
6992+ lvalue.append (rhs);
6993+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>(
6994+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
6995+ }
6996+
68336997template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
68346998bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
68356999bsl::operator +(const basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>& lhs,
68367000 CHAR_TYPE rhs)
68377001{
6838- basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result;
7002+ basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR> result (
7003+ bsl::allocator_traits<ALLOCATOR>::
7004+ select_on_container_copy_construction (lhs.get_allocator ()));
68397005 result.reserve (lhs.length () + 1 );
68407006 result += lhs;
68417007 result.push_back (rhs);
68427008 return result;
68437009}
68447010
7011+ template <class CHAR_TYPE , class CHAR_TRAITS , class ALLOCATOR >
7012+ bsl::basic_string<CHAR_TYPE,CHAR_TRAITS,ALLOCATOR>
7013+ bsl::operator +(BSLSTL_STRING_DEDUCE_RVREF lhs, CHAR_TYPE rhs)
7014+ {
7015+ basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>& lvalue = lhs;
7016+ lvalue.push_back (rhs);
7017+ return basic_string<CHAR_TYPE, CHAR_TRAITS, ALLOCATOR>(
7018+ BloombergLP::bslmf::MovableRefUtil::move (lvalue));
7019+ }
7020+
68457021template <class CHAR_TYPE , class CHAR_TRAITS >
68467022bool bslstl_string_fill (std::basic_ostream<CHAR_TYPE, CHAR_TRAITS>& os,
68477023 std::basic_streambuf<CHAR_TYPE, CHAR_TRAITS> *buf,
@@ -7084,6 +7260,10 @@ extern template class bsl::basic_string<char>;
70847260extern template class bsl ::basic_string<wchar_t >;
70857261#endif
70867262
7263+ #undef BSLSTL_STRING_DEDUCE_RVREF
7264+ #undef BSLSTL_STRING_DEDUCE_RVREF_1
7265+ #undef BSLSTL_STRING_DEDUCE_RVREF_2
7266+
70877267#endif
70887268
70897269// ----------------------------------------------------------------------------
0 commit comments