// <deque> -*- C++ -*-

// Copyright (C) 2001-2025 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/>.

/*
 *
 * Copyright (c) 1994
 * Hewlett-Packard Company
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Hewlett-Packard Company makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 *
 *
 * Copyright (c) 1997
 * Silicon Graphics Computer Systems, Inc.
 *
 * Permission to use, copy, modify, distribute and sell this software
 * and its documentation for any purpose is hereby granted without fee,
 * provided that the above copyright notice appear in all copies and
 * that both that copyright notice and this permission notice appear
 * in supporting documentation.  Silicon Graphics makes no
 * representations about the suitability of this software for any
 * purpose.  It is provided "as is" without express or implied warranty.
 */

/** @file include/deque
 *  This is a Standard C++ Library header.
 */

#ifndef _GLIBCXX_DEQUE
#define _GLIBCXX_DEQUE 1

#ifdef _GLIBCXX_SYSHDR
#pragma GCC system_header
#endif

#include <bits/requires_hosted.h> // containers are hosted only

#include <bits/stl_algobase.h>
#include <bits/allocator.h>
#include <bits/stl_construct.h>
#include <bits/stl_uninitialized.h>
#include <bits/stl_deque.h>
#include <bits/refwrap.h>
#include <bits/range_access.h>
#include <bits/deque.tcc>

#define __glibcxx_want_algorithm_default_value_type
#define __glibcxx_want_allocator_traits_is_always_equal
#define __glibcxx_want_containers_ranges
#define __glibcxx_want_erase_if
#define __glibcxx_want_nonmember_container_access
#include <bits/version.h>

#ifdef _GLIBCXX_DEBUG
# include <debug/deque>
#endif

#if __cplusplus >= 201703L
#include <bits/memory_resource.h>
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
  namespace pmr
  {
    template<typename _Tp>
      using deque = std::deque<_Tp, polymorphic_allocator<_Tp>>;
  } // namespace pmr
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // C++17

#ifdef __cpp_lib_erase_if // C++ >= 20 && erase_if
namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  template<typename _Tp, typename _Alloc, typename _Predicate>
    inline typename deque<_Tp, _Alloc>::size_type
    erase_if(deque<_Tp, _Alloc>& __cont, _Predicate __pred)
    {
      using namespace __gnu_cxx;
      _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __ucont = __cont;
      const auto __osz = __cont.size();
      const auto __end = __ucont.end();
      auto __removed = std::__remove_if(__ucont.begin(), __end,
					__ops::__pred_iter(std::ref(__pred)));
      if (__removed != __end)
	{
	  __cont.erase(__niter_wrap(__cont.begin(), __removed),
		       __cont.end());
	  return __osz - __cont.size();
	}

      return 0;
    }

  template<typename _Tp, typename _Alloc,
	   typename _Up _GLIBCXX26_DEF_VAL_T(_Tp)>
    inline typename deque<_Tp, _Alloc>::size_type
    erase(deque<_Tp, _Alloc>& __cont, const _Up& __value)
    {
      using namespace __gnu_cxx;
      _GLIBCXX_STD_C::deque<_Tp, _Alloc>& __ucont = __cont;
      const auto __osz = __cont.size();
      const auto __end = __ucont.end();
      auto __removed = std::__remove_if(__ucont.begin(), __end,
					__ops::__iter_equals_val(__value));
      if (__removed != __end)
	{
	  __cont.erase(__niter_wrap(__cont.begin(), __removed),
		       __cont.end());
	  return __osz - __cont.size();
	}

      return 0;
    }
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace std
#endif // __cpp_lib_erase_if

#endif /* _GLIBCXX_DEQUE */
