Fix testsuite failures for __gnu_debug::string with old ABI
[official-gcc.git] / libstdc++-v3 / include / debug / string
blobd330bfd5a3fa9af676af07874049676e51c166b7
1 // Debugging string implementation -*- C++ -*-
3 // Copyright (C) 2003-2018 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library.  This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License and
21 // a copy of the GCC Runtime Library Exception along with this program;
22 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
23 // <http://www.gnu.org/licenses/>.
25 /** @file debug/string
26  *  This file is a GNU debug extension to the Standard C++ Library.
27  */
29 #ifndef _GLIBCXX_DEBUG_STRING
30 #define _GLIBCXX_DEBUG_STRING 1
32 #pragma GCC system_header
34 #include <string>
35 #include <debug/safe_sequence.h>
36 #include <debug/safe_container.h>
37 #include <debug/safe_iterator.h>
39 #define _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(_Cond,_File,_Line,_Func)      \
40   if (! (_Cond))                                                        \
41     __gnu_debug::_Error_formatter::_S_at(_File, _Line, _Func)           \
42       ._M_message(#_Cond)._M_error()
44 namespace __gnu_debug
46   /** Checks that __s is non-NULL or __n == 0, and then returns __s. */
47   template<typename _CharT, typename _Integer>
48     inline const _CharT*
49     __check_string(const _CharT* __s,
50                    _Integer __n __attribute__((__unused__)),
51                    const char* __file __attribute__((__unused__)),
52                    unsigned int __line __attribute__((__unused__)),
53                    const char* __function __attribute__((__unused__)))
54     {
55 #ifdef _GLIBCXX_DEBUG_PEDANTIC
56       _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0 || __n == 0,
57                                         __file, __line, __function);
58 #endif
59       return __s;
60     }
62   /** Checks that __s is non-NULL and then returns __s. */
63   template<typename _CharT>
64     inline const _CharT*
65     __check_string(const _CharT* __s,
66                    const char* __file __attribute__((__unused__)),
67                    unsigned int __line __attribute__((__unused__)),
68                    const char* __function __attribute__((__unused__)))
69     {
70 #ifdef _GLIBCXX_DEBUG_PEDANTIC
71       _GLIBCXX_DEBUG_VERIFY_STR_COND_AT(__s != 0,
72                                         __file, __line, __function);
73 #endif
74       return __s;
75     }
77 #define __glibcxx_check_string_n_constructor(_Str, _Size) \
78   __check_string(_Str, _Size, __FILE__, __LINE__, __PRETTY_FUNCTION__)
80 #define __glibcxx_check_string_constructor(_Str) \
81   __check_string(_Str, __FILE__, __LINE__, __PRETTY_FUNCTION__)
83   /// Class std::basic_string with safety/checking/debug instrumentation.
84   template<typename _CharT, typename _Traits = std::char_traits<_CharT>,
85            typename _Allocator = std::allocator<_CharT> >
86     class basic_string
87       : public __gnu_debug::_Safe_container<
88           basic_string<_CharT, _Traits, _Allocator>,
89           _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>,
90         public std::basic_string<_CharT, _Traits, _Allocator>
91     {
92       typedef std::basic_string<_CharT, _Traits, _Allocator>    _Base;
93       typedef __gnu_debug::_Safe_container<
94         basic_string, _Allocator, _Safe_sequence, bool(_GLIBCXX_USE_CXX11_ABI)>
95       _Safe;
97       template<typename _ItT, typename _SeqT, typename _CatT>
98         friend class ::__gnu_debug::_Safe_iterator;
100       // type used for positions in insert, erase etc.
101       typedef __gnu_debug::_Safe_iterator<
102         typename _Base::__const_iterator, basic_string> __const_iterator;
104     public:
105       // types:
106       typedef _Traits                                   traits_type;
107       typedef typename _Traits::char_type               value_type;
108       typedef _Allocator                                allocator_type;
109       typedef typename _Base::size_type                 size_type;
110       typedef typename _Base::difference_type           difference_type;
111       typedef typename _Base::reference                 reference;
112       typedef typename _Base::const_reference           const_reference;
113       typedef typename _Base::pointer                   pointer;
114       typedef typename _Base::const_pointer             const_pointer;
116       typedef __gnu_debug::_Safe_iterator<
117         typename _Base::iterator, basic_string>         iterator;
118       typedef __gnu_debug::_Safe_iterator<
119         typename _Base::const_iterator, basic_string>   const_iterator;
121       typedef std::reverse_iterator<iterator>           reverse_iterator;
122       typedef std::reverse_iterator<const_iterator>     const_reverse_iterator;
124       using _Base::npos;
126       basic_string()
127         _GLIBCXX_NOEXCEPT_IF(std::is_nothrow_default_constructible<_Base>::value)
128         : _Base() { }
130       // 21.3.1 construct/copy/destroy:
131       explicit
132       basic_string(const _Allocator& __a) _GLIBCXX_NOEXCEPT
133       : _Base(__a) { }
135 #if __cplusplus < 201103L
136       basic_string(const basic_string& __str)
137       : _Base(__str) { }
139       ~basic_string() { }
140 #else
141       basic_string(const basic_string&) = default;
142       basic_string(basic_string&&) = default;
144       basic_string(std::initializer_list<_CharT> __l,
145                    const _Allocator& __a = _Allocator())
146       : _Base(__l, __a)
147       { }
149 #if _GLIBCXX_USE_CXX11_ABI
150       basic_string(const basic_string& __s, const _Allocator& __a)
151       : _Base(__s, __a) { }
153       basic_string(basic_string&& __s, const _Allocator& __a)
154       : _Base(std::move(__s), __a) { }
155 #endif
157       ~basic_string() = default;
159       // Provides conversion from a normal-mode string to a debug-mode string
160       basic_string(_Base&& __base) noexcept
161       : _Base(std::move(__base)) { }
162 #endif // C++11
164       // Provides conversion from a normal-mode string to a debug-mode string
165       basic_string(const _Base& __base)
166       : _Base(__base) { }
168       // _GLIBCXX_RESOLVE_LIB_DEFECTS
169       // 42. string ctors specify wrong default allocator
170       basic_string(const basic_string& __str, size_type __pos,
171                    size_type __n = _Base::npos,
172                    const _Allocator& __a = _Allocator())
173       : _Base(__str, __pos, __n, __a) { }
175       basic_string(const _CharT* __s, size_type __n,
176                    const _Allocator& __a = _Allocator())
177       : _Base(__glibcxx_check_string_n_constructor(__s, __n), __n, __a) { }
179       basic_string(const _CharT* __s, const _Allocator& __a = _Allocator())
180       : _Base(__glibcxx_check_string_constructor(__s), __a)
181       { this->assign(__s); }
183       basic_string(size_type __n, _CharT __c,
184                    const _Allocator& __a = _Allocator())
185       : _Base(__n, __c, __a) { }
187       template<typename _InputIterator>
188         basic_string(_InputIterator __begin, _InputIterator __end,
189                      const _Allocator& __a = _Allocator())
190         : _Base(__gnu_debug::__base(
191                   __glibcxx_check_valid_constructor_range(__begin, __end)),
192                 __gnu_debug::__base(__end), __a) { }
194 #if __cplusplus < 201103L
195       basic_string&
196       operator=(const basic_string& __str)
197       {
198         this->_M_safe() = __str;
199         _M_base() = __str;
200         return *this;
201       }
202 #else
203       basic_string&
204       operator=(const basic_string&) = default;
206       basic_string&
207       operator=(basic_string&&) = default;
208 #endif
210       basic_string&
211       operator=(const _CharT* __s)
212       {
213         __glibcxx_check_string(__s);
214         _M_base() = __s;
215         this->_M_invalidate_all();
216         return *this;
217       }
219       basic_string&
220       operator=(_CharT __c)
221       {
222         _M_base() = __c;
223         this->_M_invalidate_all();
224         return *this;
225       }
227 #if __cplusplus >= 201103L
228       basic_string&
229       operator=(std::initializer_list<_CharT> __l)
230       {
231         _M_base() = __l;
232         this->_M_invalidate_all();
233         return *this;
234       }
235 #endif // C++11
237       // 21.3.2 iterators:
238       iterator
239       begin() // _GLIBCXX_NOEXCEPT
240       { return iterator(_Base::begin(), this); }
242       const_iterator
243       begin() const _GLIBCXX_NOEXCEPT
244       { return const_iterator(_Base::begin(), this); }
246       iterator
247       end() // _GLIBCXX_NOEXCEPT
248       { return iterator(_Base::end(), this); }
250       const_iterator
251       end() const _GLIBCXX_NOEXCEPT
252       { return const_iterator(_Base::end(), this); }
254       reverse_iterator
255       rbegin() // _GLIBCXX_NOEXCEPT
256       { return reverse_iterator(end()); }
258       const_reverse_iterator
259       rbegin() const _GLIBCXX_NOEXCEPT
260       { return const_reverse_iterator(end()); }
262       reverse_iterator
263       rend() // _GLIBCXX_NOEXCEPT
264       { return reverse_iterator(begin()); }
266       const_reverse_iterator
267       rend() const _GLIBCXX_NOEXCEPT
268       { return const_reverse_iterator(begin()); }
270 #if __cplusplus >= 201103L
271       const_iterator
272       cbegin() const noexcept
273       { return const_iterator(_Base::begin(), this); }
275       const_iterator
276       cend() const noexcept
277       { return const_iterator(_Base::end(), this); }
279       const_reverse_iterator
280       crbegin() const noexcept
281       { return const_reverse_iterator(end()); }
283       const_reverse_iterator
284       crend() const noexcept
285       { return const_reverse_iterator(begin()); }
286 #endif
288       // 21.3.3 capacity:
289       using _Base::size;
290       using _Base::length;
291       using _Base::max_size;
293       void
294       resize(size_type __n, _CharT __c)
295       {
296         _Base::resize(__n, __c);
297         this->_M_invalidate_all();
298       }
300       void
301       resize(size_type __n)
302       { this->resize(__n, _CharT()); }
304 #if __cplusplus >= 201103L
305       void
306       shrink_to_fit() noexcept
307       {
308         if (capacity() > size())
309           {
310             __try
311               {
312                 reserve(0);
313                 this->_M_invalidate_all();
314               }
315             __catch(...)
316               { }
317           }
318       }
319 #endif
321       using _Base::capacity;
322       using _Base::reserve;
324       void
325       clear() // _GLIBCXX_NOEXCEPT
326       {
327         _Base::clear();
328         this->_M_invalidate_all();
329       }
331       using _Base::empty;
333       // 21.3.4 element access:
334       const_reference
335       operator[](size_type __pos) const _GLIBCXX_NOEXCEPT
336       {
337         _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
338                               _M_message(__gnu_debug::__msg_subscript_oob)
339                               ._M_sequence(*this, "this")
340                               ._M_integer(__pos, "__pos")
341                               ._M_integer(this->size(), "size"));
342         return _M_base()[__pos];
343       }
345       reference
346       operator[](size_type __pos) // _GLIBCXX_NOEXCEPT
347       {
348 #if __cplusplus < 201103L && defined(_GLIBCXX_DEBUG_PEDANTIC)
349         __glibcxx_check_subscript(__pos);
350 #else
351         // as an extension v3 allows s[s.size()] when s is non-const.
352         _GLIBCXX_DEBUG_VERIFY(__pos <= this->size(),
353                               _M_message(__gnu_debug::__msg_subscript_oob)
354                               ._M_sequence(*this, "this")
355                               ._M_integer(__pos, "__pos")
356                               ._M_integer(this->size(), "size"));
357 #endif
358         return _M_base()[__pos];
359       }
361       using _Base::at;
363 #if __cplusplus >= 201103L
364       using _Base::front;
365       using _Base::back;
366 #endif
368       // 21.3.5 modifiers:
369       basic_string&
370       operator+=(const basic_string& __str)
371       {
372         _M_base() += __str;
373         this->_M_invalidate_all();
374         return *this;
375       }
377       basic_string&
378       operator+=(const _CharT* __s)
379       {
380         __glibcxx_check_string(__s);
381         _M_base() += __s;
382         this->_M_invalidate_all();
383         return *this;
384       }
386       basic_string&
387       operator+=(_CharT __c)
388       {
389         _M_base() += __c;
390         this->_M_invalidate_all();
391         return *this;
392       }
394 #if __cplusplus >= 201103L
395       basic_string&
396       operator+=(std::initializer_list<_CharT> __l)
397       {
398         _M_base() += __l;
399         this->_M_invalidate_all();
400         return *this;
401       }
402 #endif // C++11
404       basic_string&
405       append(const basic_string& __str)
406       {
407         _Base::append(__str);
408         this->_M_invalidate_all();
409         return *this;
410       }
412       basic_string&
413       append(const basic_string& __str, size_type __pos, size_type __n)
414       {
415         _Base::append(__str, __pos, __n);
416         this->_M_invalidate_all();
417         return *this;
418       }
420       basic_string&
421       append(const _CharT* __s, size_type __n)
422       {
423         __glibcxx_check_string_len(__s, __n);
424         _Base::append(__s, __n);
425         this->_M_invalidate_all();
426         return *this;
427       }
429       basic_string&
430       append(const _CharT* __s)
431       {
432         __glibcxx_check_string(__s);
433         _Base::append(__s);
434         this->_M_invalidate_all();
435         return *this;
436       }
438       basic_string&
439       append(size_type __n, _CharT __c)
440       {
441         _Base::append(__n, __c);
442         this->_M_invalidate_all();
443         return *this;
444       }
446       template<typename _InputIterator>
447         basic_string&
448         append(_InputIterator __first, _InputIterator __last)
449         {
450           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
451           __glibcxx_check_valid_range2(__first, __last, __dist);
453           if (__dist.second >= __dp_sign)
454             _Base::append(__gnu_debug::__unsafe(__first),
455                           __gnu_debug::__unsafe(__last));
456           else
457             _Base::append(__first, __last);
459           this->_M_invalidate_all();
460           return *this;
461         }
463       // _GLIBCXX_RESOLVE_LIB_DEFECTS
464       // 7. string clause minor problems
465       void
466       push_back(_CharT __c)
467       {
468         _Base::push_back(__c);
469         this->_M_invalidate_all();
470       }
472       basic_string&
473       assign(const basic_string& __x)
474       {
475         _Base::assign(__x);
476         this->_M_invalidate_all();
477         return *this;
478       }
480 #if __cplusplus >= 201103L
481       basic_string&
482       assign(basic_string&& __x)
483       noexcept(noexcept(std::declval<_Base&>().assign(std::move(__x))))
484       {
485         _Base::assign(std::move(__x));
486         this->_M_invalidate_all();
487         return *this;
488       }
489 #endif // C++11
491       basic_string&
492       assign(const basic_string& __str, size_type __pos, size_type __n)
493       {
494         _Base::assign(__str, __pos, __n);
495         this->_M_invalidate_all();
496         return *this;
497       }
499       basic_string&
500       assign(const _CharT* __s, size_type __n)
501       {
502         __glibcxx_check_string_len(__s, __n);
503         _Base::assign(__s, __n);
504         this->_M_invalidate_all();
505         return *this;
506       }
508       basic_string&
509       assign(const _CharT* __s)
510       {
511         __glibcxx_check_string(__s);
512         _Base::assign(__s);
513         this->_M_invalidate_all();
514         return *this;
515       }
517       basic_string&
518       assign(size_type __n, _CharT __c)
519       {
520         _Base::assign(__n, __c);
521         this->_M_invalidate_all();
522         return *this;
523       }
525       template<typename _InputIterator>
526         basic_string&
527         assign(_InputIterator __first, _InputIterator __last)
528         {
529           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
530           __glibcxx_check_valid_range2(__first, __last, __dist);
532           if (__dist.second >= __dp_sign)
533             _Base::assign(__gnu_debug::__unsafe(__first),
534                           __gnu_debug::__unsafe(__last));
535           else
536             _Base::assign(__first, __last);
538           this->_M_invalidate_all();
539           return *this;
540         }
542 #if __cplusplus >= 201103L
543       basic_string&
544       assign(std::initializer_list<_CharT> __l)
545       {
546         _Base::assign(__l);
547         this->_M_invalidate_all();
548         return *this;
549       }
550 #endif // C++11
552       basic_string&
553       insert(size_type __pos1, const basic_string& __str)
554       {
555         _Base::insert(__pos1, __str);
556         this->_M_invalidate_all();
557         return *this;
558       }
560       basic_string&
561       insert(size_type __pos1, const basic_string& __str,
562              size_type __pos2, size_type __n)
563       {
564         _Base::insert(__pos1, __str, __pos2, __n);
565         this->_M_invalidate_all();
566         return *this;
567       }
569       basic_string&
570       insert(size_type __pos, const _CharT* __s, size_type __n)
571       {
572         __glibcxx_check_string(__s);
573         _Base::insert(__pos, __s, __n);
574         this->_M_invalidate_all();
575         return *this;
576       }
578       basic_string&
579       insert(size_type __pos, const _CharT* __s)
580       {
581         __glibcxx_check_string(__s);
582         _Base::insert(__pos, __s);
583         this->_M_invalidate_all();
584         return *this;
585       }
587       basic_string&
588       insert(size_type __pos, size_type __n, _CharT __c)
589       {
590         _Base::insert(__pos, __n, __c);
591         this->_M_invalidate_all();
592         return *this;
593       }
595       iterator
596       insert(__const_iterator __p, _CharT __c)
597       {
598         __glibcxx_check_insert(__p);
599         typename _Base::iterator __res = _Base::insert(__p.base(), __c);
600         this->_M_invalidate_all();
601         return iterator(__res, this);
602       }
604 #if __cplusplus >= 201103L
605       iterator
606       insert(const_iterator __p, size_type __n, _CharT __c)
607       {
608         __glibcxx_check_insert(__p);
609 #if _GLIBCXX_USE_CXX11_ABI
610         typename _Base::iterator __res = _Base::insert(__p.base(), __n, __c);
611 #else
612         const size_type __offset = __p.base() - _Base::cbegin();
613         _Base::insert(_Base::begin() + __offset, __n, __c);
614         typename _Base::iterator __res = _Base::begin() + __offset;
615 #endif
616         this->_M_invalidate_all();
617         return iterator(__res, this);
618       }
619 #else
620       void
621       insert(iterator __p, size_type __n, _CharT __c)
622       {
623         __glibcxx_check_insert(__p);
624         _Base::insert(__p.base(), __n, __c);
625         this->_M_invalidate_all();
626       }
627 #endif
629       template<typename _InputIterator>
630         iterator
631         insert(__const_iterator __p,
632                _InputIterator __first, _InputIterator __last)
633         {
634           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
635           __glibcxx_check_insert_range(__p, __first, __last, __dist);
637           typename _Base::iterator __res;
638 #if _GLIBCXX_USE_CXX11_ABI
639           if (__dist.second >= __dp_sign)
640             __res = _Base::insert(__p.base(), __gnu_debug::__unsafe(__first),
641                                   __gnu_debug::__unsafe(__last));
642           else
643             __res = _Base::insert(__p.base(), __first, __last);
644 #else
645           const size_type __offset = __p.base() - _Base::cbegin();
646           _Base::insert(__p.base(), __first, __last);
647           __res = _Base::begin() + __offset;
648 #endif
649           this->_M_invalidate_all();
650           return iterator(__res, this);
651         }
653 #if __cplusplus >= 201103L
654       iterator
655       insert(const_iterator __p, std::initializer_list<_CharT> __l)
656       {
657         __glibcxx_check_insert(__p);
658 #if _GLIBCXX_USE_CXX11_ABI
659         const auto __res = _Base::insert(__p.base(), __l);
660 #else
661         const size_type __offset = __p.base() - _Base::cbegin();
662         _Base::insert(_Base::begin() + __offset, __l);
663         auto __res = _Base::begin() + __offset;
664 #endif
665         this->_M_invalidate_all();
666         return iterator(__res, this);
667       }
668 #endif // C++11
670       basic_string&
671       erase(size_type __pos = 0, size_type __n = _Base::npos)
672       {
673         _Base::erase(__pos, __n);
674         this->_M_invalidate_all();
675         return *this;
676       }
678       iterator
679       erase(iterator __position)
680       {
681         __glibcxx_check_erase(__position);
682         typename _Base::iterator __res = _Base::erase(__position.base());
683         this->_M_invalidate_all();
684         return iterator(__res, this);
685       }
687       iterator
688       erase(iterator __first, iterator __last)
689       {
690         // _GLIBCXX_RESOLVE_LIB_DEFECTS
691         // 151. can't currently clear() empty container
692         __glibcxx_check_erase_range(__first, __last);
693         typename _Base::iterator __res = _Base::erase(__first.base(),
694                                                       __last.base());
695         this->_M_invalidate_all();
696         return iterator(__res, this);
697       }
699 #if __cplusplus >= 201103L
700       void
701       pop_back() // noexcept
702       {
703         __glibcxx_check_nonempty();
704         _Base::pop_back();
705         this->_M_invalidate_all();
706       }
707 #endif // C++11
709       basic_string&
710       replace(size_type __pos1, size_type __n1, const basic_string& __str)
711       {
712         _Base::replace(__pos1, __n1, __str);
713         this->_M_invalidate_all();
714         return *this;
715       }
717       basic_string&
718       replace(size_type __pos1, size_type __n1, const basic_string& __str,
719               size_type __pos2, size_type __n2)
720       {
721         _Base::replace(__pos1, __n1, __str, __pos2, __n2);
722         this->_M_invalidate_all();
723         return *this;
724       }
726       basic_string&
727       replace(size_type __pos, size_type __n1, const _CharT* __s,
728               size_type __n2)
729       {
730         __glibcxx_check_string_len(__s, __n2);
731         _Base::replace(__pos, __n1, __s, __n2);
732         this->_M_invalidate_all();
733         return *this;
734       }
736       basic_string&
737       replace(size_type __pos, size_type __n1, const _CharT* __s)
738       {
739         __glibcxx_check_string(__s);
740         _Base::replace(__pos, __n1, __s);
741         this->_M_invalidate_all();
742         return *this;
743       }
745       basic_string&
746       replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
747       {
748         _Base::replace(__pos, __n1, __n2, __c);
749         this->_M_invalidate_all();
750         return *this;
751       }
753       basic_string&
754       replace(__const_iterator __i1, __const_iterator __i2,
755               const basic_string& __str)
756       {
757         __glibcxx_check_erase_range(__i1, __i2);
758         _Base::replace(__i1.base(), __i2.base(), __str);
759         this->_M_invalidate_all();
760         return *this;
761       }
763       basic_string&
764       replace(__const_iterator __i1, __const_iterator __i2,
765               const _CharT* __s, size_type __n)
766       {
767         __glibcxx_check_erase_range(__i1, __i2);
768         __glibcxx_check_string_len(__s, __n);
769         _Base::replace(__i1.base(), __i2.base(), __s, __n);
770         this->_M_invalidate_all();
771         return *this;
772       }
774       basic_string&
775       replace(__const_iterator __i1, __const_iterator __i2,
776               const _CharT* __s)
777       {
778         __glibcxx_check_erase_range(__i1, __i2);
779         __glibcxx_check_string(__s);
780         _Base::replace(__i1.base(), __i2.base(), __s);
781         this->_M_invalidate_all();
782         return *this;
783       }
785       basic_string&
786       replace(__const_iterator __i1, __const_iterator __i2,
787               size_type __n, _CharT __c)
788       {
789         __glibcxx_check_erase_range(__i1, __i2);
790         _Base::replace(__i1.base(), __i2.base(), __n, __c);
791         this->_M_invalidate_all();
792         return *this;
793       }
795       template<typename _InputIterator>
796         basic_string&
797         replace(__const_iterator __i1, __const_iterator __i2,
798                 _InputIterator __j1, _InputIterator __j2)
799         {
800           __glibcxx_check_erase_range(__i1, __i2);
802           typename __gnu_debug::_Distance_traits<_InputIterator>::__type __dist;
803           __glibcxx_check_valid_range2(__j1, __j2, __dist);
805           if (__dist.second >= __dp_sign)
806             _Base::replace(__i1.base(), __i2.base(),
807                            __gnu_debug::__unsafe(__j1),
808                            __gnu_debug::__unsafe(__j2));
809           else
810             _Base::replace(__i1.base(), __i2.base(), __j1, __j2);
812           this->_M_invalidate_all();
813           return *this;
814         }
816 #if __cplusplus >= 201103L
817       basic_string&
818       replace(__const_iterator __i1, __const_iterator __i2,
819               std::initializer_list<_CharT> __l)
820       {
821         __glibcxx_check_erase_range(__i1, __i2);
822         _Base::replace(__i1.base(), __i2.base(), __l);
823         this->_M_invalidate_all();
824         return *this;
825       }
826 #endif // C++11
828       size_type
829       copy(_CharT* __s, size_type __n, size_type __pos = 0) const
830       {
831         __glibcxx_check_string_len(__s, __n);
832         return _Base::copy(__s, __n, __pos);
833       }
835       void
836       swap(basic_string& __x)
837         _GLIBCXX_NOEXCEPT_IF(std::__is_nothrow_swappable<_Base>::value)
838       {
839         _Safe::_M_swap(__x);
840         _Base::swap(__x);
841       }
843       // 21.3.6 string operations:
844       const _CharT*
845       c_str() const _GLIBCXX_NOEXCEPT
846       {
847         const _CharT* __res = _Base::c_str();
848         this->_M_invalidate_all();
849         return __res;
850       }
852       const _CharT*
853       data() const _GLIBCXX_NOEXCEPT
854       {
855         const _CharT* __res = _Base::data();
856         this->_M_invalidate_all();
857         return __res;
858       }
860       using _Base::get_allocator;
862       size_type
863       find(const basic_string& __str, size_type __pos = 0) const
864         _GLIBCXX_NOEXCEPT
865       { return _Base::find(__str, __pos); }
867       size_type
868       find(const _CharT* __s, size_type __pos, size_type __n) const
869       {
870         __glibcxx_check_string(__s);
871         return _Base::find(__s, __pos, __n);
872       }
874       size_type
875       find(const _CharT* __s, size_type __pos = 0) const
876       {
877         __glibcxx_check_string(__s);
878         return _Base::find(__s, __pos);
879       }
881       size_type
882       find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
883       { return _Base::find(__c, __pos); }
885       size_type
886       rfind(const basic_string& __str, size_type __pos = _Base::npos) const
887         _GLIBCXX_NOEXCEPT
888       { return _Base::rfind(__str, __pos); }
890       size_type
891       rfind(const _CharT* __s, size_type __pos, size_type __n) const
892       {
893         __glibcxx_check_string_len(__s, __n);
894         return _Base::rfind(__s, __pos, __n);
895       }
897       size_type
898       rfind(const _CharT* __s, size_type __pos = _Base::npos) const
899       {
900         __glibcxx_check_string(__s);
901         return _Base::rfind(__s, __pos);
902       }
904       size_type
905       rfind(_CharT __c, size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
906       { return _Base::rfind(__c, __pos); }
908       size_type
909       find_first_of(const basic_string& __str, size_type __pos = 0) const
910         _GLIBCXX_NOEXCEPT
911       { return _Base::find_first_of(__str, __pos); }
913       size_type
914       find_first_of(const _CharT* __s, size_type __pos, size_type __n) const
915       {
916         __glibcxx_check_string(__s);
917         return _Base::find_first_of(__s, __pos, __n);
918       }
920       size_type
921       find_first_of(const _CharT* __s, size_type __pos = 0) const
922       {
923         __glibcxx_check_string(__s);
924         return _Base::find_first_of(__s, __pos);
925       }
927       size_type
928       find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
929       { return _Base::find_first_of(__c, __pos); }
931       size_type
932       find_last_of(const basic_string& __str,
933                    size_type __pos = _Base::npos) const _GLIBCXX_NOEXCEPT
934       { return _Base::find_last_of(__str, __pos); }
936       size_type
937       find_last_of(const _CharT* __s, size_type __pos, size_type __n) const
938       {
939         __glibcxx_check_string(__s);
940         return _Base::find_last_of(__s, __pos, __n);
941       }
943       size_type
944       find_last_of(const _CharT* __s, size_type __pos = _Base::npos) const
945       {
946         __glibcxx_check_string(__s);
947         return _Base::find_last_of(__s, __pos);
948       }
950       size_type
951       find_last_of(_CharT __c, size_type __pos = _Base::npos) const
952         _GLIBCXX_NOEXCEPT
953       { return _Base::find_last_of(__c, __pos); }
955       size_type
956       find_first_not_of(const basic_string& __str, size_type __pos = 0) const
957         _GLIBCXX_NOEXCEPT
958       { return _Base::find_first_not_of(__str, __pos); }
960       size_type
961       find_first_not_of(const _CharT* __s, size_type __pos, size_type __n) const
962       {
963         __glibcxx_check_string_len(__s, __n);
964         return _Base::find_first_not_of(__s, __pos, __n);
965       }
967       size_type
968       find_first_not_of(const _CharT* __s, size_type __pos = 0) const
969       {
970         __glibcxx_check_string(__s);
971         return _Base::find_first_not_of(__s, __pos);
972       }
974       size_type
975       find_first_not_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
976       { return _Base::find_first_not_of(__c, __pos); }
978       size_type
979       find_last_not_of(const basic_string& __str,
980                        size_type __pos = _Base::npos) const
981         _GLIBCXX_NOEXCEPT
982       { return _Base::find_last_not_of(__str, __pos); }
984       size_type
985       find_last_not_of(const _CharT* __s, size_type __pos, size_type __n) const
986       {
987         __glibcxx_check_string(__s);
988         return _Base::find_last_not_of(__s, __pos, __n);
989       }
991       size_type
992       find_last_not_of(const _CharT* __s, size_type __pos = _Base::npos) const
993       {
994         __glibcxx_check_string(__s);
995         return _Base::find_last_not_of(__s, __pos);
996       }
998       size_type
999       find_last_not_of(_CharT __c, size_type __pos = _Base::npos) const
1000         _GLIBCXX_NOEXCEPT
1001       { return _Base::find_last_not_of(__c, __pos); }
1003       basic_string
1004       substr(size_type __pos = 0, size_type __n = _Base::npos) const
1005       { return basic_string(_Base::substr(__pos, __n)); }
1007       int
1008       compare(const basic_string& __str) const
1009       { return _Base::compare(__str); }
1011       int
1012       compare(size_type __pos1, size_type __n1,
1013               const basic_string& __str) const
1014       { return _Base::compare(__pos1, __n1, __str); }
1016       int
1017       compare(size_type __pos1, size_type __n1, const basic_string& __str,
1018               size_type __pos2, size_type __n2) const
1019       { return _Base::compare(__pos1, __n1, __str, __pos2, __n2); }
1021       int
1022       compare(const _CharT* __s) const
1023       {
1024         __glibcxx_check_string(__s);
1025         return _Base::compare(__s);
1026       }
1028       //  _GLIBCXX_RESOLVE_LIB_DEFECTS
1029       //  5. string::compare specification questionable
1030       int
1031       compare(size_type __pos1, size_type __n1, const _CharT* __s) const
1032       {
1033         __glibcxx_check_string(__s);
1034         return _Base::compare(__pos1, __n1, __s);
1035       }
1037       //  _GLIBCXX_RESOLVE_LIB_DEFECTS
1038       //  5. string::compare specification questionable
1039       int
1040       compare(size_type __pos1, size_type __n1,const _CharT* __s,
1041               size_type __n2) const
1042       {
1043         __glibcxx_check_string_len(__s, __n2);
1044         return _Base::compare(__pos1, __n1, __s, __n2);
1045       }
1047       _Base&
1048       _M_base() _GLIBCXX_NOEXCEPT               { return *this; }
1050       const _Base&
1051       _M_base() const _GLIBCXX_NOEXCEPT { return *this; }
1053       using _Safe::_M_invalidate_all;
1054     };
1056   template<typename _CharT, typename _Traits, typename _Allocator>
1057     inline basic_string<_CharT,_Traits,_Allocator>
1058     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1059               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1060     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
1062   template<typename _CharT, typename _Traits, typename _Allocator>
1063     inline basic_string<_CharT,_Traits,_Allocator>
1064     operator+(const _CharT* __lhs,
1065               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1066     {
1067       __glibcxx_check_string(__lhs);
1068       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
1069     }
1071   template<typename _CharT, typename _Traits, typename _Allocator>
1072     inline basic_string<_CharT,_Traits,_Allocator>
1073     operator+(_CharT __lhs,
1074               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1075     { return basic_string<_CharT,_Traits,_Allocator>(1, __lhs) += __rhs; }
1077   template<typename _CharT, typename _Traits, typename _Allocator>
1078     inline basic_string<_CharT,_Traits,_Allocator>
1079     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1080               const _CharT* __rhs)
1081     {
1082       __glibcxx_check_string(__rhs);
1083       return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs;
1084     }
1086   template<typename _CharT, typename _Traits, typename _Allocator>
1087     inline basic_string<_CharT,_Traits,_Allocator>
1088     operator+(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1089               _CharT __rhs)
1090     { return basic_string<_CharT,_Traits,_Allocator>(__lhs) += __rhs; }
1092   template<typename _CharT, typename _Traits, typename _Allocator>
1093     inline bool
1094     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1095                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1096     { return __lhs._M_base() == __rhs._M_base(); }
1098   template<typename _CharT, typename _Traits, typename _Allocator>
1099     inline bool
1100     operator==(const _CharT* __lhs,
1101                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1102     {
1103       __glibcxx_check_string(__lhs);
1104       return __lhs == __rhs._M_base();
1105     }
1107   template<typename _CharT, typename _Traits, typename _Allocator>
1108     inline bool
1109     operator==(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1110                const _CharT* __rhs)
1111     {
1112       __glibcxx_check_string(__rhs);
1113       return __lhs._M_base() == __rhs;
1114     }
1116   template<typename _CharT, typename _Traits, typename _Allocator>
1117     inline bool
1118     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1119                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1120     { return __lhs._M_base() != __rhs._M_base(); }
1122   template<typename _CharT, typename _Traits, typename _Allocator>
1123     inline bool
1124     operator!=(const _CharT* __lhs,
1125                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1126     {
1127       __glibcxx_check_string(__lhs);
1128       return __lhs != __rhs._M_base();
1129     }
1131   template<typename _CharT, typename _Traits, typename _Allocator>
1132     inline bool
1133     operator!=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1134                const _CharT* __rhs)
1135     {
1136       __glibcxx_check_string(__rhs);
1137       return __lhs._M_base() != __rhs;
1138     }
1140   template<typename _CharT, typename _Traits, typename _Allocator>
1141     inline bool
1142     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1143               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1144     { return __lhs._M_base() < __rhs._M_base(); }
1146   template<typename _CharT, typename _Traits, typename _Allocator>
1147     inline bool
1148     operator<(const _CharT* __lhs,
1149               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1150     {
1151       __glibcxx_check_string(__lhs);
1152       return __lhs < __rhs._M_base();
1153     }
1155   template<typename _CharT, typename _Traits, typename _Allocator>
1156     inline bool
1157     operator<(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1158               const _CharT* __rhs)
1159     {
1160       __glibcxx_check_string(__rhs);
1161       return __lhs._M_base() < __rhs;
1162     }
1164   template<typename _CharT, typename _Traits, typename _Allocator>
1165     inline bool
1166     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1167                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1168     { return __lhs._M_base() <= __rhs._M_base(); }
1170   template<typename _CharT, typename _Traits, typename _Allocator>
1171     inline bool
1172     operator<=(const _CharT* __lhs,
1173                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1174     {
1175       __glibcxx_check_string(__lhs);
1176       return __lhs <= __rhs._M_base();
1177     }
1179   template<typename _CharT, typename _Traits, typename _Allocator>
1180     inline bool
1181     operator<=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1182                const _CharT* __rhs)
1183     {
1184       __glibcxx_check_string(__rhs);
1185       return __lhs._M_base() <= __rhs;
1186     }
1188   template<typename _CharT, typename _Traits, typename _Allocator>
1189     inline bool
1190     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1191                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1192     { return __lhs._M_base() >= __rhs._M_base(); }
1194   template<typename _CharT, typename _Traits, typename _Allocator>
1195     inline bool
1196     operator>=(const _CharT* __lhs,
1197                const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1198     {
1199       __glibcxx_check_string(__lhs);
1200       return __lhs >= __rhs._M_base();
1201     }
1203   template<typename _CharT, typename _Traits, typename _Allocator>
1204     inline bool
1205     operator>=(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1206                const _CharT* __rhs)
1207     {
1208       __glibcxx_check_string(__rhs);
1209       return __lhs._M_base() >= __rhs;
1210     }
1212   template<typename _CharT, typename _Traits, typename _Allocator>
1213     inline bool
1214     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1215               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1216     { return __lhs._M_base() > __rhs._M_base(); }
1218   template<typename _CharT, typename _Traits, typename _Allocator>
1219     inline bool
1220     operator>(const _CharT* __lhs,
1221               const basic_string<_CharT,_Traits,_Allocator>& __rhs)
1222     {
1223       __glibcxx_check_string(__lhs);
1224       return __lhs > __rhs._M_base();
1225     }
1227   template<typename _CharT, typename _Traits, typename _Allocator>
1228     inline bool
1229     operator>(const basic_string<_CharT,_Traits,_Allocator>& __lhs,
1230               const _CharT* __rhs)
1231     {
1232       __glibcxx_check_string(__rhs);
1233       return __lhs._M_base() > __rhs;
1234     }
1236   // 21.3.7.8:
1237   template<typename _CharT, typename _Traits, typename _Allocator>
1238     inline void
1239     swap(basic_string<_CharT,_Traits,_Allocator>& __lhs,
1240          basic_string<_CharT,_Traits,_Allocator>& __rhs)
1241     { __lhs.swap(__rhs); }
1243   template<typename _CharT, typename _Traits, typename _Allocator>
1244     std::basic_ostream<_CharT, _Traits>&
1245     operator<<(std::basic_ostream<_CharT, _Traits>& __os,
1246                const basic_string<_CharT, _Traits, _Allocator>& __str)
1247     { return __os << __str._M_base(); }
1249   template<typename _CharT, typename _Traits, typename _Allocator>
1250     std::basic_istream<_CharT,_Traits>&
1251     operator>>(std::basic_istream<_CharT,_Traits>& __is,
1252                basic_string<_CharT,_Traits,_Allocator>& __str)
1253     {
1254       std::basic_istream<_CharT,_Traits>& __res = __is >> __str._M_base();
1255       __str._M_invalidate_all();
1256       return __res;
1257     }
1259   template<typename _CharT, typename _Traits, typename _Allocator>
1260     std::basic_istream<_CharT,_Traits>&
1261     getline(std::basic_istream<_CharT,_Traits>& __is,
1262             basic_string<_CharT,_Traits,_Allocator>& __str, _CharT __delim)
1263     {
1264       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1265                                                           __str._M_base(),
1266                                                         __delim);
1267       __str._M_invalidate_all();
1268       return __res;
1269     }
1271   template<typename _CharT, typename _Traits, typename _Allocator>
1272     std::basic_istream<_CharT,_Traits>&
1273     getline(std::basic_istream<_CharT,_Traits>& __is,
1274             basic_string<_CharT,_Traits,_Allocator>& __str)
1275     {
1276       std::basic_istream<_CharT,_Traits>& __res = getline(__is,
1277                                                           __str._M_base());
1278       __str._M_invalidate_all();
1279       return __res;
1280     }
1282   typedef basic_string<char>    string;
1284 #ifdef _GLIBCXX_USE_WCHAR_T
1285   typedef basic_string<wchar_t> wstring;
1286 #endif
1288   template<typename _CharT, typename _Traits, typename _Allocator>
1289     struct _Insert_range_from_self_is_safe<
1290       __gnu_debug::basic_string<_CharT, _Traits, _Allocator> >
1291       { enum { __value = 1 }; };
1293 } // namespace __gnu_debug
1295 #endif