libstdc++
|
00001 // Safe container implementation -*- C++ -*- 00002 00003 // Copyright (C) 2014-2015 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&& __x) noexcept 00059 : _Safe_container() 00060 { _Base::_M_swap(__x); } 00061 00062 _Safe_container(_Safe_container&& __x, 00063 const _Alloc& __a) 00064 : _Safe_container() 00065 { 00066 if (__x._M_cont().get_allocator() == __a) 00067 _Base::_M_swap(__x); 00068 else 00069 __x._M_invalidate_all(); 00070 } 00071 #endif 00072 00073 public: 00074 // Copy assignment invalidate all iterators. 00075 _Safe_container& 00076 operator=(const _Safe_container&) _GLIBCXX_NOEXCEPT 00077 { 00078 this->_M_invalidate_all(); 00079 return *this; 00080 } 00081 00082 #if __cplusplus >= 201103L 00083 _Safe_container& 00084 operator=(_Safe_container&& __x) noexcept 00085 { 00086 __glibcxx_check_self_move_assign(__x); 00087 00088 if (_IsCxx11AllocatorAware) 00089 { 00090 typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits; 00091 00092 bool __xfer_memory = _Alloc_traits::_S_propagate_on_move_assign() 00093 || _M_cont().get_allocator() == __x._M_cont().get_allocator(); 00094 if (__xfer_memory) 00095 _Base::_M_swap(__x); 00096 else 00097 this->_M_invalidate_all(); 00098 } 00099 else 00100 _Base::_M_swap(__x); 00101 00102 __x._M_invalidate_all(); 00103 return *this; 00104 } 00105 00106 void 00107 _M_swap(_Safe_container& __x) noexcept 00108 { 00109 if (_IsCxx11AllocatorAware) 00110 { 00111 typedef __gnu_cxx::__alloc_traits<_Alloc> _Alloc_traits; 00112 00113 if (!_Alloc_traits::_S_propagate_on_swap()) 00114 __glibcxx_check_equal_allocs(this->_M_cont()._M_base(), 00115 __x._M_cont()._M_base()); 00116 } 00117 00118 _Base::_M_swap(__x); 00119 } 00120 #endif 00121 }; 00122 00123 } // namespace __gnu_debug 00124 00125 #endif