libstdc++
|
00001 // Safe container implementation -*- C++ -*- 00002 00003 // Copyright (C) 2014-2017 Free Software Foundation, Inc. 00004 // 00005 // This file is part of the GNU ISO C++ Library. This library is free 00006 // software; you can redistribute it and/or modify it under the 00007 // terms of the GNU General Public License as published by the 00008 // Free Software Foundation; either version 3, or (at your option) 00009 // any later version. 00010 00011 // This library is distributed in the hope that it will be useful, 00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 // GNU General Public License for more details. 00015 00016 // Under Section 7 of GPL version 3, you are granted additional 00017 // permissions described in the GCC Runtime Library Exception, version 00018 // 3.1, as published by the Free Software Foundation. 00019 00020 // You should have received a copy of the GNU General Public License and 00021 // a copy of the GCC Runtime Library Exception along with this program; 00022 // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 00023 // <http://www.gnu.org/licenses/>. 00024 00025 /** @file debug/safe_container.h 00026 * This file is a GNU debug extension to the Standard C++ Library. 00027 */ 00028 00029 #ifndef _GLIBCXX_DEBUG_SAFE_CONTAINER_H 00030 #define _GLIBCXX_DEBUG_SAFE_CONTAINER_H 1 00031 00032 #include <ext/alloc_traits.h> 00033 00034 namespace __gnu_debug 00035 { 00036 /// Safe class dealing with some allocator dependent operations. 00037 template<typename _SafeContainer, 00038 typename _Alloc, 00039 template<typename> class _SafeBase, 00040 bool _IsCxx11AllocatorAware = true> 00041 class _Safe_container 00042 : public _SafeBase<_SafeContainer> 00043 { 00044 typedef _SafeBase<_SafeContainer> _Base; 00045 00046 _SafeContainer& 00047 _M_cont() _GLIBCXX_NOEXCEPT 00048 { return *static_cast<_SafeContainer*>(this); } 00049 00050 protected: 00051 _Safe_container& 00052 _M_safe() _GLIBCXX_NOEXCEPT 00053 { return *this; } 00054 00055 #if __cplusplus >= 201103L 00056 _Safe_container() = default; 00057 _Safe_container(const _Safe_container&) = default; 00058 _Safe_container(_Safe_container&&) = default; 00059 00060 _Safe_container(_Safe_container&& __x, const _Alloc& __a) 00061 : _Safe_container() 00062 { 00063 if (__x._M_cont().get_allocator() == __a) 00064 _Base::_M_swap(__x); 00065 else 00066 __x._M_invalidate_all(); 00067 } 00068 #endif 00069 00070 public: 00071 // Copy assignment invalidate all iterators. 00072 _Safe_container& 00073 operator=(const _Safe_container&) _GLIBCXX_NOEXCEPT 00074 { 00075 this->_M_invalidate_all(); 00076 return *this; 00077 } 00078 00079 #if __cplusplus >= 201103L 00080 _Safe_container& 00081 operator=(_Safe_container&& __x) noexcept 00082 { 00083 __glibcxx_check_self_move_assign(__x); 00084 00085 if (_IsCxx11AllocatorAware) 00086 { 00087 typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits; 00088 00089 bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign() 00090 || _M_cont().get_allocator() == __x._M_cont().get_allocator(); 00091 if (__xfer_memory) 00092 _Base::_M_swap(__x); 00093 else 00094 this->_M_invalidate_all(); 00095 } 00096 else 00097 _Base::_M_swap(__x); 00098 00099 __x._M_invalidate_all(); 00100 return *this; 00101 } 00102 00103 void 00104 _M_swap(_Safe_container& __x) noexcept 00105 { 00106 if (_IsCxx11AllocatorAware) 00107 { 00108 typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits; 00109 00110 if (!_Alloc_traits::_S_propagate_on_swap()) 00111 __glibcxx_check_equal_allocs(this->_M_cont()._M_base(), 00112 __x._M_cont()._M_base()); 00113 } 00114 00115 _Base::_M_swap(__x); 00116 } 00117 #endif 00118 }; 00119 00120 } // namespace __gnu_debug 00121 00122 #endif