// Safe sequence implementation  -*- C++ -*-

// Copyright (C) 2010-2026 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3, or (at your option)
// any later version.

// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file debug/safe_sequence.tcc
 *  This file is a GNU debug extension to the Standard C++ Library.
 */

#ifndef _GLIBCXX_DEBUG_SAFE_SEQUENCE_TCC
#define _GLIBCXX_DEBUG_SAFE_SEQUENCE_TCC 1

namespace __gnu_debug
{
  template<typename _Sequence>
    template<typename _Predicate>
      void
      _Safe_sequence<_Sequence>::
      _M_invalidate_if_impl(_Predicate __pred) const
      {
	typedef typename _Sequence::iterator iterator;
	typedef typename _Sequence::const_iterator const_iterator;

	__gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
	for (_Safe_iterator_base* __iter = _M_iterators; __iter;)
	  {
	    iterator* __victim = static_cast<iterator*>(__iter);
	    __iter = __iter->_M_next;
	    if (!__victim->_M_singular() && __pred(__victim->base()))
	      {
		__victim->_M_invalidate();
	      }
	  }

	for (_Safe_iterator_base* __iter2 = _M_const_iterators; __iter2;)
	  {
	    const_iterator* __victim = static_cast<const_iterator*>(__iter2);
	    __iter2 = __iter2->_M_next;
	    if (!__victim->_M_singular() && __pred(__victim->base()))
	      {
		__victim->_M_invalidate();
	      }
	  }
      }

  template<typename _Sequence>
    template<typename _Predicate>
      void
      _Safe_sequence<_Sequence>::
      _M_transfer_from_if(const _Safe_sequence& __from, _Predicate __pred) const
      {
	if (this == std::__addressof(__from))
	  return;

	typedef typename _Sequence::iterator iterator;
	typedef typename _Sequence::const_iterator const_iterator;

	_Safe_iterator_base* __transfered_iterators = 0;
	_Safe_iterator_base* __transfered_const_iterators = 0;
	_Safe_iterator_base* __last_iterator = 0;
	_Safe_iterator_base* __last_const_iterator = 0;
	{
	  // We lock __from first and detach iterator(s) to transfer
	  __gnu_cxx::__scoped_lock sentry(__from._M_get_mutex());

	  for (_Safe_iterator_base* __iter = __from._M_iterators; __iter;)
	    {
	      _Safe_iterator_base* __victim_base = __iter;
	      iterator* __victim = static_cast<iterator*>(__victim_base);
	      __iter = __iter->_M_next;
	      if (!__victim->_M_singular() && __pred(__victim->base()))
		{
		  __victim->_M_detach_single();
		  if (__transfered_iterators)
		    {
		      __victim_base->_M_next = __transfered_iterators;
		      __transfered_iterators->_M_prior = __victim_base;
		    }
		  else
		    __last_iterator = __victim_base;
		  __victim_base->_M_sequence = this;
		  __victim_base->_M_version = this->_M_version;
		  __transfered_iterators = __victim_base;
		}
	    }

	  for (_Safe_iterator_base* __iter2 = __from._M_const_iterators;
	       __iter2;)
	    {
	      _Safe_iterator_base* __victim_base = __iter2;
	      const_iterator* __victim =
		static_cast<const_iterator*>(__victim_base);
	      __iter2 = __iter2->_M_next;
	      if (!__victim->_M_singular() && __pred(__victim->base()))
		{
		  __victim->_M_detach_single();
		  if (__transfered_const_iterators)
		    {
		      __victim_base->_M_next = __transfered_const_iterators;
		      __transfered_const_iterators->_M_prior = __victim_base;
		    }
		  else
		    __last_const_iterator = __victim;
		  __victim_base->_M_sequence = this;
		  __victim_base->_M_version = this->_M_version;
		  __transfered_const_iterators = __victim_base;
		}
	    }
	}

	// Now we can lock *this and add the transfered iterators if any
	if (__last_iterator || __last_const_iterator)
	  {
	    __gnu_cxx::__scoped_lock sentry(this->_M_get_mutex());
	    if (__last_iterator)
	      {
		if (this->_M_iterators)
		  {
		    this->_M_iterators->_M_prior = __last_iterator;
		    __last_iterator->_M_next = this->_M_iterators;
		  }
		this->_M_iterators = __transfered_iterators;
	      }
	    if (__last_const_iterator)
	      {
		if (this->_M_const_iterators)
		  {
		    this->_M_const_iterators->_M_prior = __last_const_iterator;
		    __last_const_iterator->_M_next = this->_M_const_iterators;
		  }
		this->_M_const_iterators = __transfered_const_iterators;
	      }
	  }
      }
} // namespace __gnu_debug

#endif
