// Versatile string -*- C++ -*-

// Copyright (C) 2005-2022 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 ext/vstring.h
 *  This file is a GNU extension to the Standard C++ Library.
 */

#ifndef _VSTRING_H
#define _VSTRING_H 1

#pragma GCC system_header

#if __cplusplus >= 201103L
#include <initializer_list>
#endif

#include <ext/vstring_util.h>
#include <ext/rc_string_base.h>
#include <ext/sso_string_base.h>
#include <bits/stl_algobase.h> // std::min

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   *  @class __versa_string vstring.h
   *  @brief  Template class __versa_string. 
   *  @ingroup extensions
   *
   *  Data structure managing sequences of characters and
   *  character-like objects. 
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    class __versa_string
    : private _Base<_CharT, _Traits, _Alloc>
    {
      typedef _Base<_CharT, _Traits, _Alloc>                __vstring_base;    
      typedef typename __vstring_base::_CharT_alloc_type    _CharT_alloc_type;
      typedef __alloc_traits<_CharT_alloc_type> _CharT_alloc_traits;

      // Types:
    public:
      typedef _Traits					    traits_type;
      typedef typename _Traits::char_type		    value_type;
      typedef _Alloc					    allocator_type;
      typedef typename _CharT_alloc_type::size_type	    size_type;
      typedef typename _CharT_alloc_type::difference_type   difference_type;
      typedef value_type&               	            reference;
      typedef const value_type&                             const_reference;
      typedef typename _CharT_alloc_traits::pointer	    pointer;
      typedef typename _CharT_alloc_traits::const_pointer   const_pointer;
      typedef __gnu_cxx::__normal_iterator<pointer, __versa_string>  iterator;
      typedef __gnu_cxx::__normal_iterator<const_pointer, __versa_string>
                                                            const_iterator;
      typedef std::reverse_iterator<const_iterator>	const_reverse_iterator;
      typedef std::reverse_iterator<iterator>		    reverse_iterator;

      // Data Member (public):
      ///  Value returned by various member functions when they fail.
      static const size_type	npos = static_cast<size_type>(-1);

    private:
      size_type
      _M_check(size_type __pos, const char* __s) const
      {
	if (__pos > this->size())
	  std::__throw_out_of_range_fmt(__N("%s: __pos (which is %zu) > "
					    "this->size() (which is %zu)"),
					__s, __pos, this->size());
	return __pos;
      }

      void
      _M_check_length(size_type __n1, size_type __n2, const char* __s) const
      {
	if (this->max_size() - (this->size() - __n1) < __n2)
	  std::__throw_length_error(__N(__s));
      }

      // NB: _M_limit doesn't check for a bad __pos value.
      size_type
      _M_limit(size_type __pos, size_type __off) const _GLIBCXX_NOEXCEPT
      {
	const bool __testoff =  __off < this->size() - __pos;
	return __testoff ? __off : this->size() - __pos;
      }

      // True if _Rep and source do not overlap.
      bool
      _M_disjunct(const _CharT* __s) const _GLIBCXX_NOEXCEPT
      {
	return (std::less<const _CharT*>()(__s, this->_M_data())
		|| std::less<const _CharT*>()(this->_M_data()
					      + this->size(), __s));
      }

      // For the internal use we have functions similar to `begin'/`end'
      // but they do not call _M_leak.
      iterator
      _M_ibegin() const _GLIBCXX_NOEXCEPT
      { return iterator(this->_M_data()); }

      iterator
      _M_iend() const _GLIBCXX_NOEXCEPT
      { return iterator(this->_M_data() + this->_M_length()); }

    public:
      // Construct/copy/destroy:
      // NB: We overload ctors in some cases instead of using default
      // arguments, per 17.4.4.4 para. 2 item 2.

      /**
       *  @brief  Construct an empty string using allocator @a a.
       */
      explicit
      __versa_string(const _Alloc& __a = _Alloc()) _GLIBCXX_NOEXCEPT
      : __vstring_base(__a) { }

      // NB: per LWG issue 42, semantics different from IS:
      /**
       *  @brief  Construct string with copy of value of @a __str.
       *  @param  __str  Source string.
       */
      __versa_string(const __versa_string& __str)
      : __vstring_base(__str) { }

#if __cplusplus >= 201103L
      /**
       *  @brief  String move constructor.
       *  @param  __str  Source string.
       *
       *  The newly-constructed %string contains the exact contents of
       *  @a __str.  The contents of @a __str are a valid, but unspecified
       *  string.
       */
      __versa_string(__versa_string&& __str) noexcept
      : __vstring_base(std::move(__str)) { }

      /**
       *  @brief  Construct string from an initializer list.
       *  @param  __l  std::initializer_list of characters.
       *  @param  __a  Allocator to use (default is default allocator).
       */
      __versa_string(std::initializer_list<_CharT> __l,
		     const _Alloc& __a = _Alloc())
      : __vstring_base(__l.begin(), __l.end(), __a) { }
#endif

      /**
       *  @brief  Construct string as copy of a substring.
       *  @param  __str  Source string.
       *  @param  __pos  Index of first character to copy from.
       *  @param  __n  Number of characters to copy (default remainder).
       */
      __versa_string(const __versa_string& __str, size_type __pos,
		     size_type __n = npos)
      : __vstring_base(__str._M_data()
		       + __str._M_check(__pos,
					"__versa_string::__versa_string"),
		       __str._M_data() + __str._M_limit(__pos, __n)
		       + __pos, _Alloc()) { }

      /**
       *  @brief  Construct string as copy of a substring.
       *  @param  __str  Source string.
       *  @param  __pos  Index of first character to copy from.
       *  @param  __n  Number of characters to copy.
       *  @param  __a  Allocator to use.
       */
      __versa_string(const __versa_string& __str, size_type __pos,
		     size_type __n, const _Alloc& __a)
      : __vstring_base(__str._M_data()
		       + __str._M_check(__pos,
					"__versa_string::__versa_string"),
		       __str._M_data() + __str._M_limit(__pos, __n)
		       + __pos, __a) { }

      /**
       *  @brief  Construct string initialized by a character array.
       *  @param  __s  Source character array.
       *  @param  __n  Number of characters to copy.
       *  @param  __a  Allocator to use (default is default allocator).
       *
       *  NB: @a __s must have at least @a __n characters, '\\0' has no special
       *  meaning.
       */
      __versa_string(const _CharT* __s, size_type __n,
		     const _Alloc& __a = _Alloc())
      : __vstring_base(__s, __s + __n, __a) { }

      /**
       *  @brief  Construct string as copy of a C string.
       *  @param  __s  Source C string.
       *  @param  __a  Allocator to use (default is default allocator).
       */
      __versa_string(const _CharT* __s, const _Alloc& __a = _Alloc())
      : __vstring_base(__s, __s ? __s + traits_type::length(__s) :
		       __s + npos, __a) { }

      /**
       *  @brief  Construct string as multiple characters.
       *  @param  __n  Number of characters.
       *  @param  __c  Character to use.
       *  @param  __a  Allocator to use (default is default allocator).
       */
      __versa_string(size_type __n, _CharT __c, const _Alloc& __a = _Alloc())
      : __vstring_base(__n, __c, __a) { }

      /**
       *  @brief  Construct string as copy of a range.
       *  @param  __beg  Start of range.
       *  @param  __end  End of range.
       *  @param  __a  Allocator to use (default is default allocator).
       */
#if __cplusplus >= 201103L
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
#else
      template<class _InputIterator>
#endif
        __versa_string(_InputIterator __beg, _InputIterator __end,
		       const _Alloc& __a = _Alloc())
	: __vstring_base(__beg, __end, __a) { }

      /**
       *  @brief  Destroy the string instance.
       */
      ~__versa_string() _GLIBCXX_NOEXCEPT { }	

      /**
       *  @brief  Assign the value of @a str to this string.
       *  @param  __str  Source string.
       */
      __versa_string&
      operator=(const __versa_string& __str) 
      { return this->assign(__str); }

#if __cplusplus >= 201103L
      /**
       *  @brief  String move assignment operator.
       *  @param  __str  Source string.
       *
       *  The contents of @a __str are moved into this string (without
       *  copying).  @a __str is a valid, but unspecified string.
       */
      __versa_string&
      operator=(__versa_string&& __str) noexcept
      {
	// NB: DR 1204.
	this->swap(__str);
	return *this;
      }

      /**
       *  @brief  Set value to string constructed from initializer list.
       *  @param  __l  std::initializer_list.
       */
      __versa_string&
      operator=(std::initializer_list<_CharT> __l)
      {
	this->assign(__l.begin(), __l.end());
	return *this;
      }
#endif

      /**
       *  @brief  Copy contents of @a __s into this string.
       *  @param  __s  Source null-terminated string.
       */
      __versa_string&
      operator=(const _CharT* __s) 
      { return this->assign(__s); }

      /**
       *  @brief  Set value to string of length 1.
       *  @param  __c  Source character.
       *
       *  Assigning to a character makes this string length 1 and
       *  (*this)[0] == @a __c.
       */
      __versa_string&
      operator=(_CharT __c) 
      { 
	this->assign(1, __c); 
	return *this;
      }

      // Iterators:
      /**
       *  Returns a read/write iterator that points to the first character in
       *  the %string.  Unshares the string.
       */
      iterator
      begin() _GLIBCXX_NOEXCEPT
      {
	this->_M_leak();
	return iterator(this->_M_data());
      }

      /**
       *  Returns a read-only (constant) iterator that points to the first
       *  character in the %string.
       */
      const_iterator
      begin() const _GLIBCXX_NOEXCEPT
      { return const_iterator(this->_M_data()); }

      /**
       *  Returns a read/write iterator that points one past the last
       *  character in the %string.  Unshares the string.
       */
      iterator
      end() _GLIBCXX_NOEXCEPT
      {
	this->_M_leak();
	return iterator(this->_M_data() + this->size());
      }

      /**
       *  Returns a read-only (constant) iterator that points one past the
       *  last character in the %string.
       */
      const_iterator
      end() const _GLIBCXX_NOEXCEPT
      { return const_iterator(this->_M_data() + this->size()); }

      /**
       *  Returns a read/write reverse iterator that points to the last
       *  character in the %string.  Iteration is done in reverse element
       *  order.  Unshares the string.
       */
      reverse_iterator
      rbegin() _GLIBCXX_NOEXCEPT
      { return reverse_iterator(this->end()); }

      /**
       *  Returns a read-only (constant) reverse iterator that points
       *  to the last character in the %string.  Iteration is done in
       *  reverse element order.
       */
      const_reverse_iterator
      rbegin() const _GLIBCXX_NOEXCEPT
      { return const_reverse_iterator(this->end()); }

      /**
       *  Returns a read/write reverse iterator that points to one before the
       *  first character in the %string.  Iteration is done in reverse
       *  element order.  Unshares the string.
       */
      reverse_iterator
      rend() _GLIBCXX_NOEXCEPT
      { return reverse_iterator(this->begin()); }

      /**
       *  Returns a read-only (constant) reverse iterator that points
       *  to one before the first character in the %string.  Iteration
       *  is done in reverse element order.
       */
      const_reverse_iterator
      rend() const _GLIBCXX_NOEXCEPT
      { return const_reverse_iterator(this->begin()); }

#if __cplusplus >= 201103L
      /**
       *  Returns a read-only (constant) iterator that points to the first
       *  character in the %string.
       */
      const_iterator
      cbegin() const noexcept
      { return const_iterator(this->_M_data()); }

      /**
       *  Returns a read-only (constant) iterator that points one past the
       *  last character in the %string.
       */
      const_iterator
      cend() const noexcept
      { return const_iterator(this->_M_data() + this->size()); }

      /**
       *  Returns a read-only (constant) reverse iterator that points
       *  to the last character in the %string.  Iteration is done in
       *  reverse element order.
       */
      const_reverse_iterator
      crbegin() const noexcept
      { return const_reverse_iterator(this->end()); }

      /**
       *  Returns a read-only (constant) reverse iterator that points
       *  to one before the first character in the %string.  Iteration
       *  is done in reverse element order.
       */
      const_reverse_iterator
      crend() const noexcept
      { return const_reverse_iterator(this->begin()); }
#endif

    public:
      // Capacity:
      ///  Returns the number of characters in the string, not including any
      ///  null-termination.
      size_type
      size() const _GLIBCXX_NOEXCEPT
      { return this->_M_length(); }

      ///  Returns the number of characters in the string, not including any
      ///  null-termination.
      size_type
      length() const _GLIBCXX_NOEXCEPT
      { return this->_M_length(); }

      /// Returns the size() of the largest possible %string.
      size_type
      max_size() const _GLIBCXX_NOEXCEPT
      { return this->_M_max_size(); }

      /**
       *  @brief  Resizes the %string to the specified number of characters.
       *  @param  __n  Number of characters the %string should contain.
       *  @param  __c  Character to fill any new elements.
       *
       *  This function will %resize the %string to the specified
       *  number of characters.  If the number is smaller than the
       *  %string's current size the %string is truncated, otherwise
       *  the %string is extended and new elements are set to @a __c.
       */
      void
      resize(size_type __n, _CharT __c);

      /**
       *  @brief  Resizes the %string to the specified number of characters.
       *  @param  __n  Number of characters the %string should contain.
       *
       *  This function will resize the %string to the specified
       *  length.  If the new size is smaller than the %string's
       *  current size the %string is truncated, otherwise the %string
       *  is extended and new characters are default-constructed.  For
       *  basic types such as char, this means setting them to 0.
       */
      void
      resize(size_type __n)
      { this->resize(__n, _CharT()); }

#if __cplusplus >= 201103L
      /// A non-binding request to reduce capacity() to size().
      void
      shrink_to_fit() noexcept
      {
	if (capacity() > size())
	  {
	    __try
	      { this->reserve(0); }
	    __catch(...)
	      { }
	  }
      }
#endif

      /**
       *  Returns the total number of characters that the %string can
       *  hold before needing to allocate more memory.
       */
      size_type
      capacity() const _GLIBCXX_NOEXCEPT
      { return this->_M_capacity(); }

      /**
       *  @brief  Attempt to preallocate enough memory for specified number of
       *          characters.
       *  @param  __res_arg  Number of characters required.
       *  @throw  std::length_error  If @a __res_arg exceeds @c max_size().
       *
       *  This function attempts to reserve enough memory for the
       *  %string to hold the specified number of characters.  If the
       *  number requested is more than max_size(), length_error is
       *  thrown.
       *
       *  The advantage of this function is that if optimal code is a
       *  necessity and the user can determine the string length that
       *  will be required, the user can reserve the memory in
       *  %advance, and thus prevent a possible reallocation of memory
       *  and copying of %string data.
       */
      void
      reserve(size_type __res_arg = 0)
      { this->_M_reserve(__res_arg); }

      /**
       *  Erases the string, making it empty.
       */
      void
      clear() _GLIBCXX_NOEXCEPT
      { this->_M_clear(); }

      /**
       *  Returns true if the %string is empty.  Equivalent to 
       *  <code>*this == ""</code>.
       */
      _GLIBCXX_NODISCARD bool
      empty() const _GLIBCXX_NOEXCEPT
      { return this->size() == 0; }

      // Element access:
      /**
       *  @brief  Subscript access to the data contained in the %string.
       *  @param  __pos  The index of the character to access.
       *  @return  Read-only (constant) reference to the character.
       *
       *  This operator allows for easy, array-style, data access.
       *  Note that data access with this operator is unchecked and
       *  out_of_range lookups are not defined. (For checked lookups
       *  see at().)
       */
      const_reference
      operator[] (size_type __pos) const _GLIBCXX_NOEXCEPT
      {
	__glibcxx_assert(__pos <= this->size());
	return this->_M_data()[__pos];
      }

      /**
       *  @brief  Subscript access to the data contained in the %string.
       *  @param  __pos  The index of the character to access.
       *  @return  Read/write reference to the character.
       *
       *  This operator allows for easy, array-style, data access.
       *  Note that data access with this operator is unchecked and
       *  out_of_range lookups are not defined. (For checked lookups
       *  see at().)  Unshares the string.
       */
      reference
      operator[](size_type __pos) _GLIBCXX_NOEXCEPT
      {
        // Allow pos == size() both in C++98 mode, as v3 extension,
	// and in C++11 mode.
	__glibcxx_assert(__pos <= this->size());
        // In pedantic mode be strict in C++98 mode.
	_GLIBCXX_DEBUG_PEDASSERT(__cplusplus >= 201103L
				 || __pos < this->size());
	this->_M_leak();
	return this->_M_data()[__pos];
      }

      /**
       *  @brief  Provides access to the data contained in the %string.
       *  @param __n The index of the character to access.
       *  @return  Read-only (const) reference to the character.
       *  @throw  std::out_of_range  If @a __n is an invalid index.
       *
       *  This function provides for safer data access.  The parameter
       *  is first checked that it is in the range of the string.  The
       *  function throws out_of_range if the check fails.
       */
      const_reference
      at(size_type __n) const
      {
	if (__n >= this->size())
	  std::__throw_out_of_range_fmt(__N("__versa_string::at: __n "
					    "(which is %zu) >= this->size() "
					    "(which is %zu)"),
					__n, this->size());
	return this->_M_data()[__n];
      }

      /**
       *  @brief  Provides access to the data contained in the %string.
       *  @param __n The index of the character to access.
       *  @return  Read/write reference to the character.
       *  @throw  std::out_of_range  If @a __n is an invalid index.
       *
       *  This function provides for safer data access.  The parameter
       *  is first checked that it is in the range of the string.  The
       *  function throws out_of_range if the check fails.  Success
       *  results in unsharing the string.
       */
      reference
      at(size_type __n)
      {
	if (__n >= this->size())
	  std::__throw_out_of_range_fmt(__N("__versa_string::at: __n "
					    "(which is %zu) >= this->size() "
					    "(which is %zu)"),
					__n, this->size());
	this->_M_leak();
	return this->_M_data()[__n];
      }

#if __cplusplus >= 201103L
      /**
       *  Returns a read/write reference to the data at the first
       *  element of the %string.
       */
      reference
      front() noexcept
      { return operator[](0); }

      /**
       *  Returns a read-only (constant) reference to the data at the first
       *  element of the %string.
       */
      const_reference
      front() const noexcept
      { return operator[](0); }

      /**
       *  Returns a read/write reference to the data at the last
       *  element of the %string.
       */
      reference
      back() noexcept
      { return operator[](this->size() - 1); }

      /**
       *  Returns a read-only (constant) reference to the data at the
       *  last element of the %string.
       */
      const_reference
      back() const noexcept
      { return operator[](this->size() - 1); }
#endif

      // Modifiers:
      /**
       *  @brief  Append a string to this string.
       *  @param __str  The string to append.
       *  @return  Reference to this string.
       */
      __versa_string&
      operator+=(const __versa_string& __str)
      { return this->append(__str); }

      /**
       *  @brief  Append a C string.
       *  @param __s  The C string to append.
       *  @return  Reference to this string.
       */
      __versa_string&
      operator+=(const _CharT* __s)
      { return this->append(__s); }

      /**
       *  @brief  Append a character.
       *  @param __c  The character to append.
       *  @return  Reference to this string.
       */
      __versa_string&
      operator+=(_CharT __c)
      { 
	this->push_back(__c);
	return *this;
      }

#if __cplusplus >= 201103L
      /**
       *  @brief  Append an initializer_list of characters.
       *  @param __l  The initializer_list of characters to be appended.
       *  @return  Reference to this string.
       */
      __versa_string&
      operator+=(std::initializer_list<_CharT> __l)
      { return this->append(__l.begin(), __l.end()); }
#endif // C++11

      /**
       *  @brief  Append a string to this string.
       *  @param __str  The string to append.
       *  @return  Reference to this string.
       */
      __versa_string&
      append(const __versa_string& __str)
      { return _M_append(__str._M_data(), __str.size()); }

      /**
       *  @brief  Append a substring.
       *  @param __str  The string to append.
       *  @param __pos  Index of the first character of str to append.
       *  @param __n  The number of characters to append.
       *  @return  Reference to this string.
       *  @throw  std::out_of_range if @a pos is not a valid index.
       *
       *  This function appends @a __n characters from @a __str
       *  starting at @a __pos to this string.  If @a __n is is larger
       *  than the number of available characters in @a __str, the
       *  remainder of @a __str is appended.
       */
      __versa_string&
      append(const __versa_string& __str, size_type __pos, size_type __n)
      { return _M_append(__str._M_data()
			 + __str._M_check(__pos, "__versa_string::append"),
			 __str._M_limit(__pos, __n)); }

      /**
       *  @brief  Append a C substring.
       *  @param __s  The C string to append.
       *  @param __n  The number of characters to append.
       *  @return  Reference to this string.
       */
      __versa_string&
      append(const _CharT* __s, size_type __n)
      {
	__glibcxx_requires_string_len(__s, __n);
	_M_check_length(size_type(0), __n, "__versa_string::append");
	return _M_append(__s, __n);
      }

      /**
       *  @brief  Append a C string.
       *  @param __s  The C string to append.
       *  @return  Reference to this string.
       */
      __versa_string&
      append(const _CharT* __s)
      {
	__glibcxx_requires_string(__s);
	const size_type __n = traits_type::length(__s);
	_M_check_length(size_type(0), __n, "__versa_string::append");
	return _M_append(__s, __n);
      }

      /**
       *  @brief  Append multiple characters.
       *  @param __n  The number of characters to append.
       *  @param __c  The character to use.
       *  @return  Reference to this string.
       *
       *  Appends n copies of c to this string.
       */
      __versa_string&
      append(size_type __n, _CharT __c)
      { return _M_replace_aux(this->size(), size_type(0), __n, __c); }

#if __cplusplus >= 201103L
      /**
       *  @brief  Append an initializer_list of characters.
       *  @param __l  The initializer_list of characters to append.
       *  @return  Reference to this string.
       */
      __versa_string&
      append(std::initializer_list<_CharT> __l)
      { return this->append(__l.begin(), __l.end()); }
#endif // C++11

      /**
       *  @brief  Append a range of characters.
       *  @param __first  Iterator referencing the first character to append.
       *  @param __last  Iterator marking the end of the range.
       *  @return  Reference to this string.
       *
       *  Appends characters in the range [first,last) to this string.
       */
#if __cplusplus >= 201103L
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
#else
      template<class _InputIterator>
#endif
        __versa_string&
        append(_InputIterator __first, _InputIterator __last)
        { return this->replace(_M_iend(), _M_iend(), __first, __last); }

      /**
       *  @brief  Append a single character.
       *  @param __c  Character to append.
       */
      void
      push_back(_CharT __c)
      { 
	const size_type __size = this->size();
	if (__size + 1 > this->capacity() || this->_M_is_shared())
	  this->_M_mutate(__size, size_type(0), 0, size_type(1));
	traits_type::assign(this->_M_data()[__size], __c);
	this->_M_set_length(__size + 1);
      }

      /**
       *  @brief  Set value to contents of another string.
       *  @param  __str  Source string to use.
       *  @return  Reference to this string.
       */
      __versa_string&
      assign(const __versa_string& __str)
      {
	this->_M_assign(__str);
	return *this;
      }

#if __cplusplus >= 201103L
      /**
       *  @brief  Set value to contents of another string.
       *  @param  __str  Source string to use.
       *  @return  Reference to this string.
       *
       *  This function sets this string to the exact contents of @a __str.
       *  @a __str is a valid, but unspecified string.
       */
      __versa_string&
      assign(__versa_string&& __str) noexcept
      {
	this->swap(__str);
	return *this;
      }
#endif // C++11

      /**
       *  @brief  Set value to a substring of a string.
       *  @param __str  The string to use.
       *  @param __pos  Index of the first character of str.
       *  @param __n  Number of characters to use.
       *  @return  Reference to this string.
       *  @throw  std::out_of_range if @a __pos is not a valid index.
       *
       *  This function sets this string to the substring of @a __str
       *  consisting of @a __n characters at @a __pos.  If @a __n is
       *  is larger than the number of available characters in @a
       *  __str, the remainder of @a __str is used.
       */
      __versa_string&
      assign(const __versa_string& __str, size_type __pos, size_type __n)
      { return _M_replace(size_type(0), this->size(), __str._M_data()
			  + __str._M_check(__pos, "__versa_string::assign"),
			  __str._M_limit(__pos, __n)); }

      /**
       *  @brief  Set value to a C substring.
       *  @param __s  The C string to use.
       *  @param __n  Number of characters to use.
       *  @return  Reference to this string.
       *
       *  This function sets the value of this string to the first @a
       *  __n characters of @a __s.  If @a __n is is larger than the
       *  number of available characters in @a __s, the remainder of
       *  @a __s is used.
       */
      __versa_string&
      assign(const _CharT* __s, size_type __n)
      {
	__glibcxx_requires_string_len(__s, __n);
	return _M_replace(size_type(0), this->size(), __s, __n);
      }

      /**
       *  @brief  Set value to contents of a C string.
       *  @param __s  The C string to use.
       *  @return  Reference to this string.
       *
       *  This function sets the value of this string to the value of
       *  @a __s.  The data is copied, so there is no dependence on @a
       *  __s once the function returns.
       */
      __versa_string&
      assign(const _CharT* __s)
      {
	__glibcxx_requires_string(__s);
	return _M_replace(size_type(0), this->size(), __s,
			  traits_type::length(__s));
      }

      /**
       *  @brief  Set value to multiple characters.
       *  @param __n  Length of the resulting string.
       *  @param __c  The character to use.
       *  @return  Reference to this string.
       *
       *  This function sets the value of this string to @a __n copies of
       *  character @a __c.
       */
      __versa_string&
      assign(size_type __n, _CharT __c)
      { return _M_replace_aux(size_type(0), this->size(), __n, __c); }

      /**
       *  @brief  Set value to a range of characters.
       *  @param __first  Iterator referencing the first character to append.
       *  @param __last  Iterator marking the end of the range.
       *  @return  Reference to this string.
       *
       *  Sets value of string to characters in the range
       *  [first,last).
      */
#if __cplusplus >= 201103L
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
#else
      template<class _InputIterator>
#endif
        __versa_string&
        assign(_InputIterator __first, _InputIterator __last)
        { return this->replace(_M_ibegin(), _M_iend(), __first, __last); }

#if __cplusplus >= 201103L
      /**
       *  @brief  Set value to an initializer_list of characters.
       *  @param __l  The initializer_list of characters to assign.
       *  @return  Reference to this string.
       */
      __versa_string&
      assign(std::initializer_list<_CharT> __l)
      { return this->assign(__l.begin(), __l.end()); }
#endif // C++11

#if __cplusplus >= 201103L
      /**
       *  @brief  Insert multiple characters.
       *  @param __p  Const_iterator referencing location in string to
       *              insert at.
       *  @param __n  Number of characters to insert
       *  @param __c  The character to insert.
       *  @return  Iterator referencing the first inserted char.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Inserts @a __n copies of character @a __c starting at the
       *  position referenced by iterator @a __p.  If adding
       *  characters causes the length to exceed max_size(),
       *  length_error is thrown.  The value of the string doesn't
       *  change if an error is thrown.
      */
      iterator
      insert(const_iterator __p, size_type __n, _CharT __c)
      {
	_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
	const size_type __pos = __p - _M_ibegin();
	this->replace(__p, __p, __n, __c);
	return iterator(this->_M_data() + __pos); 
      }
#else
      /**
       *  @brief  Insert multiple characters.
       *  @param __p  Iterator referencing location in string to insert at.
       *  @param __n  Number of characters to insert
       *  @param __c  The character to insert.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Inserts @a __n copies of character @a __c starting at the
       *  position referenced by iterator @a __p.  If adding
       *  characters causes the length to exceed max_size(),
       *  length_error is thrown.  The value of the string doesn't
       *  change if an error is thrown.
      */
      void
      insert(iterator __p, size_type __n, _CharT __c)
      {	this->replace(__p, __p, __n, __c);  }
#endif

#if __cplusplus >= 201103L
      /**
       *  @brief  Insert a range of characters.
       *  @param __p  Const_iterator referencing location in string to
       *              insert at.
       *  @param __beg  Start of range.
       *  @param __end  End of range.
       *  @return  Iterator referencing the first inserted char.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Inserts characters in range [beg,end).  If adding characters
       *  causes the length to exceed max_size(), length_error is
       *  thrown.  The value of the string doesn't change if an error
       *  is thrown.
      */
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
	iterator
        insert(const_iterator __p, _InputIterator __beg, _InputIterator __end)
        {
	  _GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
	  const size_type __pos = __p - _M_ibegin();
	  this->replace(__p, __p, __beg, __end);
	  return iterator(this->_M_data() + __pos);
	}
#else
      /**
       *  @brief  Insert a range of characters.
       *  @param __p  Iterator referencing location in string to insert at.
       *  @param __beg  Start of range.
       *  @param __end  End of range.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Inserts characters in range [beg,end).  If adding characters
       *  causes the length to exceed max_size(), length_error is
       *  thrown.  The value of the string doesn't change if an error
       *  is thrown.
      */
      template<class _InputIterator>
        void
        insert(iterator __p, _InputIterator __beg, _InputIterator __end)
        { this->replace(__p, __p, __beg, __end); }
#endif

#if __cplusplus >= 201103L
      /**
       *  @brief  Insert an initializer_list of characters.
       *  @param __p  Const_iterator referencing location in string to
       *              insert at.
       *  @param __l  The initializer_list of characters to insert.
       *  @return  Iterator referencing the first inserted char.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       */
      iterator
      insert(const_iterator __p, std::initializer_list<_CharT> __l)
      { return this->insert(__p, __l.begin(), __l.end()); }
#endif // C++11

      /**
       *  @brief  Insert value of a string.
       *  @param __pos1  Iterator referencing location in string to insert at.
       *  @param __str  The string to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Inserts value of @a __str starting at @a __pos1.  If adding
       *  characters causes the length to exceed max_size(),
       *  length_error is thrown.  The value of the string doesn't
       *  change if an error is thrown.
      */
      __versa_string&
      insert(size_type __pos1, const __versa_string& __str)
      { return this->replace(__pos1, size_type(0),
			     __str._M_data(), __str.size()); }

      /**
       *  @brief  Insert a substring.
       *  @param __pos1  Iterator referencing location in string to insert at.
       *  @param __str  The string to insert.
       *  @param __pos2  Start of characters in str to insert.
       *  @param __n  Number of characters to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *  @throw  std::out_of_range  If @a __pos1 > size() or
       *  @a __pos2 > @a __str.size().
       *
       *  Starting at @a __pos1, insert @a __n character of @a __str
       *  beginning with @a __pos2.  If adding characters causes the
       *  length to exceed max_size(), length_error is thrown.  If @a
       *  __pos1 is beyond the end of this string or @a __pos2 is
       *  beyond the end of @a __str, out_of_range is thrown.  The
       *  value of the string doesn't change if an error is thrown.
      */
      __versa_string&
      insert(size_type __pos1, const __versa_string& __str,
	     size_type __pos2, size_type __n)
      { return this->replace(__pos1, size_type(0), __str._M_data()
			     + __str._M_check(__pos2, "__versa_string::insert"),
			     __str._M_limit(__pos2, __n)); }

      /**
       *  @brief  Insert a C substring.
       *  @param __pos  Iterator referencing location in string to insert at.
       *  @param __s  The C string to insert.
       *  @param __n  The number of characters to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *  @throw  std::out_of_range  If @a __pos is beyond the end of this
       *  string.
       *
       *  Inserts the first @a __n characters of @a __s starting at @a
       *  __pos.  If adding characters causes the length to exceed
       *  max_size(), length_error is thrown.  If @a __pos is beyond
       *  end(), out_of_range is thrown.  The value of the string
       *  doesn't change if an error is thrown.
      */
      __versa_string&
      insert(size_type __pos, const _CharT* __s, size_type __n)
      { return this->replace(__pos, size_type(0), __s, __n); }

      /**
       *  @brief  Insert a C string.
       *  @param __pos  Iterator referencing location in string to insert at.
       *  @param __s  The C string to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *  @throw  std::out_of_range  If @a __pos is beyond the end of this
       *  string.
       *
       *  Inserts the first @a __n characters of @a __s starting at @a
       *  __pos.  If adding characters causes the length to exceed
       *  max_size(), length_error is thrown.  If @a __pos is beyond
       *  end(), out_of_range is thrown.  The value of the string
       *  doesn't change if an error is thrown.
      */
      __versa_string&
      insert(size_type __pos, const _CharT* __s)
      {
	__glibcxx_requires_string(__s);
	return this->replace(__pos, size_type(0), __s,
			     traits_type::length(__s));
      }

      /**
       *  @brief  Insert multiple characters.
       *  @param __pos  Index in string to insert at.
       *  @param __n  Number of characters to insert
       *  @param __c  The character to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *  @throw  std::out_of_range  If @a __pos is beyond the end of this
       *  string.
       *
       *  Inserts @a __n copies of character @a __c starting at index
       *  @a __pos.  If adding characters causes the length to exceed
       *  max_size(), length_error is thrown.  If @a __pos > length(),
       *  out_of_range is thrown.  The value of the string doesn't
       *  change if an error is thrown.
      */
      __versa_string&
      insert(size_type __pos, size_type __n, _CharT __c)
      { return _M_replace_aux(_M_check(__pos, "__versa_string::insert"),
			      size_type(0), __n, __c); }

      /**
       *  @brief  Insert one character.
       *  @param __p  Iterator referencing position in string to insert at.
       *  @param __c  The character to insert.
       *  @return  Iterator referencing newly inserted char.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Inserts character @a __c at position referenced by @a __p.
       *  If adding character causes the length to exceed max_size(),
       *  length_error is thrown.  If @a __p is beyond end of string,
       *  out_of_range is thrown.  The value of the string doesn't
       *  change if an error is thrown.
      */
      iterator
#if __cplusplus >= 201103L
      insert(const_iterator __p, _CharT __c)
#else
      insert(iterator __p, _CharT __c)	
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(__p >= _M_ibegin() && __p <= _M_iend());
	const size_type __pos = __p - _M_ibegin();
	_M_replace_aux(__pos, size_type(0), size_type(1), __c);
	this->_M_set_leaked();
	return iterator(this->_M_data() + __pos);
      }

      /**
       *  @brief  Remove characters.
       *  @param __pos  Index of first character to remove (default 0).
       *  @param __n  Number of characters to remove (default remainder).
       *  @return  Reference to this string.
       *  @throw  std::out_of_range  If @a __pos is beyond the end of this
       *  string.
       *
       *  Removes @a __n characters from this string starting at @a
       *  __pos.  The length of the string is reduced by @a __n.  If
       *  there are < @a __n characters to remove, the remainder of
       *  the string is truncated.  If @a __p is beyond end of string,
       *  out_of_range is thrown.  The value of the string doesn't
       *  change if an error is thrown.
      */
      __versa_string&
      erase(size_type __pos = 0, size_type __n = npos)
      { 
	this->_M_erase(_M_check(__pos, "__versa_string::erase"),
		       _M_limit(__pos, __n));
	return *this;
      }

      /**
       *  @brief  Remove one character.
       *  @param __position  Iterator referencing the character to remove.
       *  @return  iterator referencing same location after removal.
       *
       *  Removes the character at @a __position from this string. The
       *  value of the string doesn't change if an error is thrown.
      */
      iterator
#if __cplusplus >= 201103L
      erase(const_iterator __position)
#else
      erase(iterator __position)	
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(__position >= _M_ibegin()
				 && __position < _M_iend());
	const size_type __pos = __position - _M_ibegin();
	this->_M_erase(__pos, size_type(1));
	this->_M_set_leaked();
	return iterator(this->_M_data() + __pos);
      }

      /**
       *  @brief  Remove a range of characters.
       *  @param __first  Iterator referencing the first character to remove.
       *  @param __last  Iterator referencing the end of the range.
       *  @return  Iterator referencing location of first after removal.
       *
       *  Removes the characters in the range [first,last) from this
       *  string.  The value of the string doesn't change if an error
       *  is thrown.
      */
      iterator
#if __cplusplus >= 201103L
      erase(const_iterator __first, const_iterator __last)
#else
      erase(iterator __first, iterator __last)
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(__first >= _M_ibegin() && __first <= __last
				 && __last <= _M_iend());
        const size_type __pos = __first - _M_ibegin();
	this->_M_erase(__pos, __last - __first);
	this->_M_set_leaked();
	return iterator(this->_M_data() + __pos);
      }

#if __cplusplus >= 201103L
      /**
       *  @brief  Remove the last character.
       *
       *  The string must be non-empty.
       */
      void
      pop_back()
      { this->_M_erase(size()-1, 1); }
#endif // C++11

      /**
       *  @brief  Replace characters with value from another string.
       *  @param __pos  Index of first character to replace.
       *  @param __n  Number of characters to be replaced.
       *  @param __str  String to insert.
       *  @return  Reference to this string.
       *  @throw  std::out_of_range  If @a __pos is beyond the end of this
       *  string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [pos,pos+n) from this
       *  string.  In place, the value of @a __str is inserted.  If @a
       *  __pos is beyond end of string, out_of_range is thrown.  If
       *  the length of the result exceeds max_size(), length_error is
       *  thrown.  The value of the string doesn't change if an error
       *  is thrown.
      */
      __versa_string&
      replace(size_type __pos, size_type __n, const __versa_string& __str)
      { return this->replace(__pos, __n, __str._M_data(), __str.size()); }

      /**
       *  @brief  Replace characters with value from another string.
       *  @param __pos1  Index of first character to replace.
       *  @param __n1  Number of characters to be replaced.
       *  @param __str  String to insert.
       *  @param __pos2  Index of first character of str to use.
       *  @param __n2  Number of characters from str to use.
       *  @return  Reference to this string.
       *  @throw  std::out_of_range  If @a __pos1 > size() or @a __pos2 >
       *  str.size().
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [pos1,pos1 + n) from
       *  this string.  In place, the value of @a __str is inserted.
       *  If @a __pos is beyond end of string, out_of_range is thrown.
       *  If the length of the result exceeds max_size(), length_error
       *  is thrown.  The value of the string doesn't change if an
       *  error is thrown.
      */
      __versa_string&
      replace(size_type __pos1, size_type __n1, const __versa_string& __str,
	      size_type __pos2, size_type __n2)
      {
	return this->replace(__pos1, __n1, __str._M_data()
			     + __str._M_check(__pos2,
					      "__versa_string::replace"),
			     __str._M_limit(__pos2, __n2));
      }

      /**
       *  @brief  Replace characters with value of a C substring.
       *  @param __pos  Index of first character to replace.
       *  @param __n1  Number of characters to be replaced.
       *  @param __s  C string to insert.
       *  @param __n2  Number of characters from @a __s to use.
       *  @return  Reference to this string.
       *  @throw  std::out_of_range  If @a __pos1 > size().
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [pos,pos + n1) from this
       *  string.  In place, the first @a __n2 characters of @a __s
       *  are inserted, or all of @a __s if @a __n2 is too large.  If
       *  @a __pos is beyond end of string, out_of_range is thrown.
       *  If the length of result exceeds max_size(), length_error is
       *  thrown.  The value of the string doesn't change if an error
       *  is thrown.
      */
      __versa_string&
      replace(size_type __pos, size_type __n1, const _CharT* __s,
	      size_type __n2)
      {
	__glibcxx_requires_string_len(__s, __n2);
	return _M_replace(_M_check(__pos, "__versa_string::replace"),
			  _M_limit(__pos, __n1), __s, __n2);
      }

      /**
       *  @brief  Replace characters with value of a C string.
       *  @param __pos  Index of first character to replace.
       *  @param __n1  Number of characters to be replaced.
       *  @param __s  C string to insert.
       *  @return  Reference to this string.
       *  @throw  std::out_of_range  If @a __pos > size().
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [pos,pos + n1) from this
       *  string.  In place, the characters of @a __s are inserted.  If
       *  @a pos is beyond end of string, out_of_range is thrown.  If
       *  the length of result exceeds max_size(), length_error is thrown.  
       *  The value of the string doesn't change if an error is thrown.
      */
      __versa_string&
      replace(size_type __pos, size_type __n1, const _CharT* __s)
      {
	__glibcxx_requires_string(__s);
	return this->replace(__pos, __n1, __s, traits_type::length(__s));
      }

      /**
       *  @brief  Replace characters with multiple characters.
       *  @param __pos  Index of first character to replace.
       *  @param __n1  Number of characters to be replaced.
       *  @param __n2  Number of characters to insert.
       *  @param __c  Character to insert.
       *  @return  Reference to this string.
       *  @throw  std::out_of_range  If @a __pos > size().
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [pos,pos + n1) from this
       *  string.  In place, @a __n2 copies of @a __c are inserted.
       *  If @a __pos is beyond end of string, out_of_range is thrown.
       *  If the length of result exceeds max_size(), length_error is
       *  thrown.  The value of the string doesn't change if an error
       *  is thrown.
      */
      __versa_string&
      replace(size_type __pos, size_type __n1, size_type __n2, _CharT __c)
      { return _M_replace_aux(_M_check(__pos, "__versa_string::replace"),
			      _M_limit(__pos, __n1), __n2, __c); }

      /**
       *  @brief  Replace range of characters with string.
       *  @param __i1  Iterator referencing start of range to replace.
       *  @param __i2  Iterator referencing end of range to replace.
       *  @param __str  String value to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [i1,i2).  In place, the
       *  value of @a __str is inserted.  If the length of result
       *  exceeds max_size(), length_error is thrown.  The value of
       *  the string doesn't change if an error is thrown.
      */
      __versa_string&
#if __cplusplus >= 201103L
      replace(const_iterator __i1, const_iterator __i2,
	      const __versa_string& __str)
#else
      replace(iterator __i1, iterator __i2, const __versa_string& __str)
#endif
      { return this->replace(__i1, __i2, __str._M_data(), __str.size()); }

      /**
       *  @brief  Replace range of characters with C substring.
       *  @param __i1  Iterator referencing start of range to replace.
       *  @param __i2  Iterator referencing end of range to replace.
       *  @param __s  C string value to insert.
       *  @param __n  Number of characters from s to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [i1,i2).  In place, the
       *  first @a n characters of @a __s are inserted.  If the length
       *  of result exceeds max_size(), length_error is thrown.  The
       *  value of the string doesn't change if an error is thrown.
      */
      __versa_string&
#if __cplusplus >= 201103L
      replace(const_iterator __i1, const_iterator __i2,
	      const _CharT* __s, size_type __n)
#else
      replace(iterator __i1, iterator __i2, const _CharT* __s, size_type __n)
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
				 && __i2 <= _M_iend());
	return this->replace(__i1 - _M_ibegin(), __i2 - __i1, __s, __n);
      }

      /**
       *  @brief  Replace range of characters with C string.
       *  @param __i1  Iterator referencing start of range to replace.
       *  @param __i2  Iterator referencing end of range to replace.
       *  @param __s  C string value to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [i1,i2).  In place, the
       *  characters of @a __s are inserted.  If the length of result
       *  exceeds max_size(), length_error is thrown.  The value of
       *  the string doesn't change if an error is thrown.
      */
      __versa_string&
#if __cplusplus >= 201103L
      replace(const_iterator __i1, const_iterator __i2, const _CharT* __s)
#else
      replace(iterator __i1, iterator __i2, const _CharT* __s)	
#endif
      {
	__glibcxx_requires_string(__s);
	return this->replace(__i1, __i2, __s, traits_type::length(__s));
      }

      /**
       *  @brief  Replace range of characters with multiple characters
       *  @param __i1  Iterator referencing start of range to replace.
       *  @param __i2  Iterator referencing end of range to replace.
       *  @param __n  Number of characters to insert.
       *  @param __c  Character to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [i1,i2).  In place, @a
       *  __n copies of @a __c are inserted.  If the length of result
       *  exceeds max_size(), length_error is thrown.  The value of
       *  the string doesn't change if an error is thrown.
      */
      __versa_string&
#if __cplusplus >= 201103L
      replace(const_iterator __i1, const_iterator __i2, size_type __n,
	      _CharT __c)
#else
      replace(iterator __i1, iterator __i2, size_type __n, _CharT __c)
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
				 && __i2 <= _M_iend());
	return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __c);
      }

      /**
       *  @brief  Replace range of characters with range.
       *  @param __i1  Iterator referencing start of range to replace.
       *  @param __i2  Iterator referencing end of range to replace.
       *  @param __k1  Iterator referencing start of range to insert.
       *  @param __k2  Iterator referencing end of range to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [i1,i2).  In place,
       *  characters in the range [k1,k2) are inserted.  If the length
       *  of result exceeds max_size(), length_error is thrown.  The
       *  value of the string doesn't change if an error is thrown.
      */
#if __cplusplus >= 201103L
      template<class _InputIterator,
	       typename = std::_RequireInputIter<_InputIterator>>
        __versa_string&
        replace(const_iterator __i1, const_iterator __i2,
		_InputIterator __k1, _InputIterator __k2)
        {
	  _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
				   && __i2 <= _M_iend());
	  __glibcxx_requires_valid_range(__k1, __k2);
	  return this->_M_replace_dispatch(__i1, __i2, __k1, __k2,
					   std::__false_type());
	}
#else
      template<class _InputIterator>
        __versa_string&
        replace(iterator __i1, iterator __i2,
		_InputIterator __k1, _InputIterator __k2)
        {
	  _GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
				   && __i2 <= _M_iend());
	  __glibcxx_requires_valid_range(__k1, __k2);
	  typedef typename std::__is_integer<_InputIterator>::__type _Integral;
	  return this->_M_replace_dispatch(__i1, __i2, __k1, __k2, _Integral());
	}
#endif

      // Specializations for the common case of pointer and iterator:
      // useful to avoid the overhead of temporary buffering in _M_replace.
      __versa_string&
#if __cplusplus >= 201103L
      replace(const_iterator __i1, const_iterator __i2,
	      _CharT* __k1, _CharT* __k2)
#else
      replace(iterator __i1, iterator __i2,
	      _CharT* __k1, _CharT* __k2)
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
				 && __i2 <= _M_iend());
	__glibcxx_requires_valid_range(__k1, __k2);
	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
			     __k1, __k2 - __k1);
      }

      __versa_string&
#if __cplusplus >= 201103L
      replace(const_iterator __i1, const_iterator __i2,
	      const _CharT* __k1, const _CharT* __k2)
#else
      replace(iterator __i1, iterator __i2,
	      const _CharT* __k1, const _CharT* __k2)
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
				 && __i2 <= _M_iend());
	__glibcxx_requires_valid_range(__k1, __k2);
	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
			     __k1, __k2 - __k1);
      }

      __versa_string&
#if __cplusplus >= 201103L
      replace(const_iterator __i1, const_iterator __i2,
	      iterator __k1, iterator __k2)
#else
      replace(iterator __i1, iterator __i2,
	      iterator __k1, iterator __k2)
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
				 && __i2 <= _M_iend());
	__glibcxx_requires_valid_range(__k1, __k2);
	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
			     __k1.base(), __k2 - __k1);
      }

      __versa_string&
#if __cplusplus >= 201103L
      replace(const_iterator __i1, const_iterator __i2,
	      const_iterator __k1, const_iterator __k2)
#else
      replace(iterator __i1, iterator __i2,
	      const_iterator __k1, const_iterator __k2)
#endif
      {
	_GLIBCXX_DEBUG_PEDASSERT(_M_ibegin() <= __i1 && __i1 <= __i2
				 && __i2 <= _M_iend());
	__glibcxx_requires_valid_range(__k1, __k2);
	return this->replace(__i1 - _M_ibegin(), __i2 - __i1,
			     __k1.base(), __k2 - __k1);
      }
      
#if __cplusplus >= 201103L
      /**
       *  @brief  Replace range of characters with initializer_list.
       *  @param __i1  Iterator referencing start of range to replace.
       *  @param __i2  Iterator referencing end of range to replace.
       *  @param __l  The initializer_list of characters to insert.
       *  @return  Reference to this string.
       *  @throw  std::length_error  If new length exceeds @c max_size().
       *
       *  Removes the characters in the range [i1,i2).  In place,
       *  characters in the range [k1,k2) are inserted.  If the length
       *  of result exceeds max_size(), length_error is thrown.  The
       *  value of the string doesn't change if an error is thrown.
      */
      __versa_string&
      replace(const_iterator __i1, const_iterator __i2,
	      std::initializer_list<_CharT> __l)
      { return this->replace(__i1, __i2, __l.begin(), __l.end()); }
#endif // C++11

    private:
      template<class _Integer>
	__versa_string&
	_M_replace_dispatch(const_iterator __i1, const_iterator __i2,
			    _Integer __n, _Integer __val, std::__true_type)
        { return _M_replace_aux(__i1 - _M_ibegin(), __i2 - __i1, __n, __val); }

      template<class _InputIterator>
	__versa_string&
	_M_replace_dispatch(const_iterator __i1, const_iterator __i2,
			    _InputIterator __k1, _InputIterator __k2,
			    std::__false_type);

      __versa_string&
      _M_replace_aux(size_type __pos1, size_type __n1, size_type __n2,
		     _CharT __c);

      __versa_string&
      _M_replace(size_type __pos, size_type __len1, const _CharT* __s,
		 const size_type __len2);

      __versa_string&
      _M_append(const _CharT* __s, size_type __n);

    public:

      /**
       *  @brief  Copy substring into C string.
       *  @param __s  C string to copy value into.
       *  @param __n  Number of characters to copy.
       *  @param __pos  Index of first character to copy.
       *  @return  Number of characters actually copied
       *  @throw  std::out_of_range  If pos > size().
       *
       *  Copies up to @a __n characters starting at @a __pos into the
       *  C string @a s.  If @a __pos is greater than size(),
       *  out_of_range is thrown.
      */
      size_type
      copy(_CharT* __s, size_type __n, size_type __pos = 0) const;

      /**
       *  @brief  Swap contents with another string.
       *  @param __s  String to swap with.
       *
       *  Exchanges the contents of this string with that of @a __s in
       *  constant time.
      */
      void
      swap(__versa_string& __s) _GLIBCXX_NOEXCEPT
      { this->_M_swap(__s); }

      // String operations:
      /**
       *  @brief  Return const pointer to null-terminated contents.
       *
       *  This is a handle to internal data.  Do not modify or dire things may
       *  happen.
      */
      const _CharT*
      c_str() const _GLIBCXX_NOEXCEPT
      { return this->_M_data(); }

      /**
       *  @brief  Return const pointer to contents.
       *
       *  This is a handle to internal data.  Do not modify or dire things may
       *  happen.
      */
      const _CharT*
      data() const _GLIBCXX_NOEXCEPT
      { return this->_M_data(); }

      /**
       *  @brief  Return copy of allocator used to construct this string.
      */
      allocator_type
      get_allocator() const _GLIBCXX_NOEXCEPT
      { return allocator_type(this->_M_get_allocator()); }

      /**
       *  @brief  Find position of a C substring.
       *  @param __s  C string to locate.
       *  @param __pos  Index of character to search from.
       *  @param __n  Number of characters from @a __s to search for.
       *  @return  Index of start of first occurrence.
       *
       *  Starting from @a __pos, searches forward for the first @a
       *  __n characters in @a __s within this string.  If found,
       *  returns the index where it begins.  If not found, returns
       *  npos.
      */
      size_type
      find(const _CharT* __s, size_type __pos, size_type __n) const;

      /**
       *  @brief  Find position of a string.
       *  @param __str  String to locate.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of start of first occurrence.
       *
       *  Starting from @a __pos, searches forward for value of @a
       *  __str within this string.  If found, returns the index where
       *  it begins.  If not found, returns npos.
      */
      size_type
      find(const __versa_string& __str, size_type __pos = 0) const
	_GLIBCXX_NOEXCEPT
      { return this->find(__str.data(), __pos, __str.size()); }

      /**
       *  @brief  Find position of a C string.
       *  @param __s  C string to locate.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of start of first occurrence.
       *
       *  Starting from @a __pos, searches forward for the value of @a
       *  __s within this string.  If found, returns the index where
       *  it begins.  If not found, returns npos.
      */
      size_type
      find(const _CharT* __s, size_type __pos = 0) const
      {
	__glibcxx_requires_string(__s);
	return this->find(__s, __pos, traits_type::length(__s));
      }

      /**
       *  @brief  Find position of a character.
       *  @param __c  Character to locate.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for @a __c within
       *  this string.  If found, returns the index where it was
       *  found.  If not found, returns npos.
      */
      size_type
      find(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT;

      /**
       *  @brief  Find last position of a string.
       *  @param __str  String to locate.
       *  @param __pos  Index of character to search back from (default end).
       *  @return  Index of start of last occurrence.
       *
       *  Starting from @a __pos, searches backward for value of @a
       *  __str within this string.  If found, returns the index where
       *  it begins.  If not found, returns npos.
      */
      size_type
      rfind(const __versa_string& __str, size_type __pos = npos) const
	_GLIBCXX_NOEXCEPT
      { return this->rfind(__str.data(), __pos, __str.size()); }

      /**
       *  @brief  Find last position of a C substring.
       *  @param __s  C string to locate.
       *  @param __pos  Index of character to search back from.
       *  @param __n  Number of characters from s to search for.
       *  @return  Index of start of last occurrence.
       *
       *  Starting from @a __pos, searches backward for the first @a
       *  __n characters in @a __s within this string.  If found,
       *  returns the index where it begins.  If not found, returns
       *  npos.
      */
      size_type
      rfind(const _CharT* __s, size_type __pos, size_type __n) const;

      /**
       *  @brief  Find last position of a C string.
       *  @param __s  C string to locate.
       *  @param __pos  Index of character to start search at (default end).
       *  @return  Index of start of  last occurrence.
       *
       *  Starting from @a __pos, searches backward for the value of
       *  @a __s within this string.  If found, returns the index
       *  where it begins.  If not found, returns npos.
      */
      size_type
      rfind(const _CharT* __s, size_type __pos = npos) const
      {
	__glibcxx_requires_string(__s);
	return this->rfind(__s, __pos, traits_type::length(__s));
      }

      /**
       *  @brief  Find last position of a character.
       *  @param __c  Character to locate.
       *  @param __pos  Index of character to search back from (default end).
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for @a __c within
       *  this string.  If found, returns the index where it was
       *  found.  If not found, returns npos.
      */
      size_type
      rfind(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT;

      /**
       *  @brief  Find position of a character of string.
       *  @param __str  String containing characters to locate.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for one of the characters of
       *  @a __str within this string.  If found, returns the index where it was
       *  found.  If not found, returns npos.
      */
      size_type
      find_first_of(const __versa_string& __str, size_type __pos = 0) const
	_GLIBCXX_NOEXCEPT
      { return this->find_first_of(__str.data(), __pos, __str.size()); }

      /**
       *  @brief  Find position of a character of C substring.
       *  @param __s  String containing characters to locate.
       *  @param __pos  Index of character to search from.
       *  @param __n  Number of characters from s to search for.
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for one of the
       *  first @a __n characters of @a __s within this string.  If
       *  found, returns the index where it was found.  If not found,
       *  returns npos.
      */
      size_type
      find_first_of(const _CharT* __s, size_type __pos, size_type __n) const;

      /**
       *  @brief  Find position of a character of C string.
       *  @param __s  String containing characters to locate.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for one of the
       *  characters of @a __s within this string.  If found, returns
       *  the index where it was found.  If not found, returns npos.
      */
      size_type
      find_first_of(const _CharT* __s, size_type __pos = 0) const
      {
	__glibcxx_requires_string(__s);
	return this->find_first_of(__s, __pos, traits_type::length(__s));
      }

      /**
       *  @brief  Find position of a character.
       *  @param __c  Character to locate.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for the character
       *  @a __c within this string.  If found, returns the index
       *  where it was found.  If not found, returns npos.
       *
       *  Note: equivalent to find(c, pos).
      */
      size_type
      find_first_of(_CharT __c, size_type __pos = 0) const _GLIBCXX_NOEXCEPT
      { return this->find(__c, __pos); }

      /**
       *  @brief  Find last position of a character of string.
       *  @param __str  String containing characters to locate.
       *  @param __pos  Index of character to search back from (default end).
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for one of the
       *  characters of @a __str within this string.  If found,
       *  returns the index where it was found.  If not found, returns
       *  npos.
      */
      size_type
      find_last_of(const __versa_string& __str, size_type __pos = npos) const
	_GLIBCXX_NOEXCEPT
      { return this->find_last_of(__str.data(), __pos, __str.size()); }

      /**
       *  @brief  Find last position of a character of C substring.
       *  @param __s  C string containing characters to locate.
       *  @param __pos  Index of character to search back from.
       *  @param __n  Number of characters from s to search for.
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for one of the
       *  first @a __n characters of @a __s within this string.  If
       *  found, returns the index where it was found.  If not found,
       *  returns npos.
      */
      size_type
      find_last_of(const _CharT* __s, size_type __pos, size_type __n) const;

      /**
       *  @brief  Find last position of a character of C string.
       *  @param __s  C string containing characters to locate.
       *  @param __pos  Index of character to search back from (default end).
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for one of the
       *  characters of @a __s within this string.  If found, returns
       *  the index where it was found.  If not found, returns npos.
      */
      size_type
      find_last_of(const _CharT* __s, size_type __pos = npos) const
      {
	__glibcxx_requires_string(__s);
	return this->find_last_of(__s, __pos, traits_type::length(__s));
      }

      /**
       *  @brief  Find last position of a character.
       *  @param __c  Character to locate.
       *  @param __pos  Index of character to search back from (default end).
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for @a __c within
       *  this string.  If found, returns the index where it was
       *  found.  If not found, returns npos.
       *
       *  Note: equivalent to rfind(c, pos).
      */
      size_type
      find_last_of(_CharT __c, size_type __pos = npos) const _GLIBCXX_NOEXCEPT
      { return this->rfind(__c, __pos); }

      /**
       *  @brief  Find position of a character not in string.
       *  @param __str  String containing characters to avoid.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for a character not
       *  contained in @a __str within this string.  If found, returns
       *  the index where it was found.  If not found, returns npos.
      */
      size_type
      find_first_not_of(const __versa_string& __str, size_type __pos = 0) const
	_GLIBCXX_NOEXCEPT
      { return this->find_first_not_of(__str.data(), __pos, __str.size()); }

      /**
       *  @brief  Find position of a character not in C substring.
       *  @param __s  C string containing characters to avoid.
       *  @param __pos  Index of character to search from.
       *  @param __n  Number of characters from s to consider.
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for a character not
       *  contained in the first @a __n characters of @a __s within
       *  this string.  If found, returns the index where it was
       *  found.  If not found, returns npos.
      */
      size_type
      find_first_not_of(const _CharT* __s, size_type __pos,
			size_type __n) const;

      /**
       *  @brief  Find position of a character not in C string.
       *  @param __s  C string containing characters to avoid.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for a character not
       *  contained in @a __s within this string.  If found, returns
       *  the index where it was found.  If not found, returns npos.
      */
      size_type
      find_first_not_of(const _CharT* __s, size_type __pos = 0) const
      {
	__glibcxx_requires_string(__s);
	return this->find_first_not_of(__s, __pos, traits_type::length(__s));
      }

      /**
       *  @brief  Find position of a different character.
       *  @param __c  Character to avoid.
       *  @param __pos  Index of character to search from (default 0).
       *  @return  Index of first occurrence.
       *
       *  Starting from @a __pos, searches forward for a character
       *  other than @a __c within this string.  If found, returns the
       *  index where it was found.  If not found, returns npos.
      */
      size_type
      find_first_not_of(_CharT __c, size_type __pos = 0) const
	_GLIBCXX_NOEXCEPT;

      /**
       *  @brief  Find last position of a character not in string.
       *  @param __str  String containing characters to avoid.
       *  @param __pos  Index of character to search back from (default end).
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for a character
       *  not contained in @a __str within this string.  If found,
       *  returns the index where it was found.  If not found, returns
       *  npos.
      */
      size_type
      find_last_not_of(const __versa_string& __str,
		       size_type __pos = npos) const _GLIBCXX_NOEXCEPT
      { return this->find_last_not_of(__str.data(), __pos, __str.size()); }

      /**
       *  @brief  Find last position of a character not in C substring.
       *  @param __s  C string containing characters to avoid.
       *  @param __pos  Index of character to search back from.
       *  @param __n  Number of characters from s to consider.
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for a character
       *  not contained in the first @a __n characters of @a __s
       *  within this string.  If found, returns the index where it
       *  was found.  If not found, returns npos.
      */
      size_type
      find_last_not_of(const _CharT* __s, size_type __pos,
		       size_type __n) const;
      /**
       *  @brief  Find last position of a character not in C string.
       *  @param __s  C string containing characters to avoid.
       *  @param __pos  Index of character to search back from (default end).
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for a character
       *  not contained in @a __s within this string.  If found,
       *  returns the index where it was found.  If not found, returns
       *  npos.
      */
      size_type
      find_last_not_of(const _CharT* __s, size_type __pos = npos) const
      {
	__glibcxx_requires_string(__s);
	return this->find_last_not_of(__s, __pos, traits_type::length(__s));
      }

      /**
       *  @brief  Find last position of a different character.
       *  @param __c  Character to avoid.
       *  @param __pos  Index of character to search back from (default end).
       *  @return  Index of last occurrence.
       *
       *  Starting from @a __pos, searches backward for a character
       *  other than @a __c within this string.  If found, returns the
       *  index where it was found.  If not found, returns npos.
      */
      size_type
      find_last_not_of(_CharT __c, size_type __pos = npos) const
	_GLIBCXX_NOEXCEPT;

      /**
       *  @brief  Get a substring.
       *  @param __pos  Index of first character (default 0).
       *  @param __n  Number of characters in substring (default remainder).
       *  @return  The new string.
       *  @throw  std::out_of_range  If pos > size().
       *
       *  Construct and return a new string using the @a __n
       *  characters starting at @a __pos.  If the string is too
       *  short, use the remainder of the characters.  If @a __pos is
       *  beyond the end of the string, out_of_range is thrown.
      */
      __versa_string
      substr(size_type __pos = 0, size_type __n = npos) const
      {
	return __versa_string(*this, _M_check(__pos, "__versa_string::substr"),
			      __n);
      }

      /**
       *  @brief  Compare to a string.
       *  @param __str  String to compare against.
       *  @return  Integer < 0, 0, or > 0.
       *
       *  Returns an integer < 0 if this string is ordered before @a
       *  __str, 0 if their values are equivalent, or > 0 if this
       *  string is ordered after @a __str.  Determines the effective
       *  length rlen of the strings to compare as the smallest of
       *  size() and str.size().  The function then compares the two
       *  strings by calling traits::compare(data(), str.data(),rlen).
       *  If the result of the comparison is nonzero returns it,
       *  otherwise the shorter one is ordered first.
      */
      int
      compare(const __versa_string& __str) const
      {
	if (this->_M_compare(__str))
	  return 0;

	const size_type __size = this->size();
	const size_type __osize = __str.size();
	const size_type __len = std::min(__size, __osize);

	int __r = traits_type::compare(this->_M_data(), __str.data(), __len);
	if (!__r)
	  __r = this->_S_compare(__size, __osize);
	return __r;
      }

      /**
       *  @brief  Compare substring to a string.
       *  @param __pos  Index of first character of substring.
       *  @param __n  Number of characters in substring.
       *  @param __str  String to compare against.
       *  @return  Integer < 0, 0, or > 0.
       *
       *  Form the substring of this string from the @a __n characters
       *  starting at @a __pos.  Returns an integer < 0 if the
       *  substring is ordered before @a __str, 0 if their values are
       *  equivalent, or > 0 if the substring is ordered after @a
       *  __str.  Determines the effective length rlen of the strings
       *  to compare as the smallest of the length of the substring
       *  and @a __str.size().  The function then compares the two
       *  strings by calling
       *  traits::compare(substring.data(),str.data(),rlen).  If the
       *  result of the comparison is nonzero returns it, otherwise
       *  the shorter one is ordered first.
      */
      int
      compare(size_type __pos, size_type __n,
	      const __versa_string& __str) const;

      /**
       *  @brief  Compare substring to a substring.
       *  @param __pos1  Index of first character of substring.
       *  @param __n1  Number of characters in substring.
       *  @param __str  String to compare against.
       *  @param __pos2  Index of first character of substring of str.
       *  @param __n2  Number of characters in substring of str.
       *  @return  Integer < 0, 0, or > 0.
       *
       *  Form the substring of this string from the @a __n1
       *  characters starting at @a __pos1.  Form the substring of @a
       *  __str from the @a __n2 characters starting at @a __pos2.
       *  Returns an integer < 0 if this substring is ordered before
       *  the substring of @a __str, 0 if their values are equivalent,
       *  or > 0 if this substring is ordered after the substring of
       *  @a __str.  Determines the effective length rlen of the
       *  strings to compare as the smallest of the lengths of the
       *  substrings.  The function then compares the two strings by
       *  calling
       *  traits::compare(substring.data(),str.substr(pos2,n2).data(),rlen).
       *  If the result of the comparison is nonzero returns it,
       *  otherwise the shorter one is ordered first.
      */
      int
      compare(size_type __pos1, size_type __n1, const __versa_string& __str,
	      size_type __pos2, size_type __n2) const;

      /**
       *  @brief  Compare to a C string.
       *  @param __s  C string to compare against.
       *  @return  Integer < 0, 0, or > 0.
       *
       *  Returns an integer < 0 if this string is ordered before @a
       *  __s, 0 if their values are equivalent, or > 0 if this string
       *  is ordered after @a __s.  Determines the effective length
       *  rlen of the strings to compare as the smallest of size() and
       *  the length of a string constructed from @a __s.  The
       *  function then compares the two strings by calling
       *  traits::compare(data(),s,rlen).  If the result of the
       *  comparison is nonzero returns it, otherwise the shorter one
       *  is ordered first.
      */
      int
      compare(const _CharT* __s) const;

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 5 String::compare specification questionable
      /**
       *  @brief  Compare substring to a C string.
       *  @param __pos  Index of first character of substring.
       *  @param __n1  Number of characters in substring.
       *  @param __s  C string to compare against.
       *  @return  Integer < 0, 0, or > 0.
       *
       *  Form the substring of this string from the @a __n1
       *  characters starting at @a __pos.  Returns an integer < 0 if
       *  the substring is ordered before @a __s, 0 if their values
       *  are equivalent, or > 0 if the substring is ordered after @a
       *  __s.  Determines the effective length rlen of the strings to
       *  compare as the smallest of the length of the substring and
       *  the length of a string constructed from @a __s.  The
       *  function then compares the two string by calling
       *  traits::compare(substring.data(),s,rlen).  If the result of
       *  the comparison is nonzero returns it, otherwise the shorter
       *  one is ordered first.
      */
      int
      compare(size_type __pos, size_type __n1, const _CharT* __s) const;

      /**
       *  @brief  Compare substring against a character array.
       *  @param __pos  Index of first character of substring.
       *  @param __n1  Number of characters in substring.
       *  @param __s  character array to compare against.
       *  @param __n2  Number of characters of s.
       *  @return  Integer < 0, 0, or > 0.
       *
       *  Form the substring of this string from the @a __n1
       *  characters starting at @a __pos.  Form a string from the
       *  first @a __n2 characters of @a __s.  Returns an integer < 0
       *  if this substring is ordered before the string from @a __s,
       *  0 if their values are equivalent, or > 0 if this substring
       *  is ordered after the string from @a __s.  Determines the
       *  effective length rlen of the strings to compare as the
       *  smallest of the length of the substring and @a __n2.  The
       *  function then compares the two strings by calling
       *  traits::compare(substring.data(),__s,rlen).  If the result of
       *  the comparison is nonzero returns it, otherwise the shorter
       *  one is ordered first.
       *
       *  NB: __s must have at least n2 characters, <em>\\0</em> has no special
       *  meaning.
      */
      int
      compare(size_type __pos, size_type __n1, const _CharT* __s,
	      size_type __n2) const;
    };

  // operator+
  /**
   *  @brief  Concatenate two strings.
   *  @param __lhs  First string.
   *  @param __rhs  Last string.
   *  @return  New string with value of @a __lhs followed by @a __rhs.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs);

  /**
   *  @brief  Concatenate C string and string.
   *  @param __lhs  First string.
   *  @param __rhs  Last string.
   *  @return  New string with value of @a __lhs followed by @a __rhs.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(const _CharT* __lhs,
	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs);

  /**
   *  @brief  Concatenate character and string.
   *  @param __lhs  First string.
   *  @param __rhs  Last string.
   *  @return  New string with @a __lhs followed by @a __rhs.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(_CharT __lhs,
	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs);

  /**
   *  @brief  Concatenate string and C string.
   *  @param __lhs  First string.
   *  @param __rhs  Last string.
   *  @return  New string with @a __lhs followed by @a __rhs.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	      const _CharT* __rhs);

  /**
   *  @brief  Concatenate string and character.
   *  @param __lhs  First string.
   *  @param __rhs  Last string.
   *  @return  New string with @a __lhs followed by @a __rhs.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	      _CharT __rhs);

#if __cplusplus >= 201103L
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs,
	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return std::move(__lhs.append(__rhs)); }

  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	      __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs)
    { return std::move(__rhs.insert(0, __lhs)); }

  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs,
	      __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs)
    {
      const auto __size = __lhs.size() + __rhs.size();
      const bool __cond = (__size > __lhs.capacity()
			   && __size <= __rhs.capacity());
      return __cond ? std::move(__rhs.insert(0, __lhs))
	            : std::move(__lhs.append(__rhs));
    }

  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(const _CharT* __lhs,
	      __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs)
    { return std::move(__rhs.insert(0, __lhs)); }

  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(_CharT __lhs,
	      __versa_string<_CharT, _Traits, _Alloc, _Base>&& __rhs)
    { return std::move(__rhs.insert(0, 1, __lhs)); }

  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs,
	      const _CharT* __rhs)
    { return std::move(__lhs.append(__rhs)); }

  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline __versa_string<_CharT, _Traits, _Alloc, _Base>
    operator+(__versa_string<_CharT, _Traits, _Alloc, _Base>&& __lhs,
	      _CharT __rhs)
    { return std::move(__lhs.append(1, __rhs)); }
#endif

  // operator ==
  /**
   *  @brief  Test equivalence of two strings.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __lhs.compare(__rhs) == 0; }

  template<typename _CharT,
	   template <typename, typename, typename> class _Base>
    inline typename __enable_if<std::__is_char<_CharT>::__value, bool>::__type
    operator==(const __versa_string<_CharT, std::char_traits<_CharT>,
	       std::allocator<_CharT>, _Base>& __lhs,
	       const __versa_string<_CharT, std::char_traits<_CharT>,
	       std::allocator<_CharT>, _Base>& __rhs)
    { return (__lhs.size() == __rhs.size()
	      && !std::char_traits<_CharT>::compare(__lhs.data(), __rhs.data(),
						    __lhs.size())); }

  /**
   *  @brief  Test equivalence of C string and string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __rhs.compare(@a __lhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator==(const _CharT* __lhs,
	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __rhs.compare(__lhs) == 0; }

  /**
   *  @brief  Test equivalence of string and C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs.compare(@a __rhs) == 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator==(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	       const _CharT* __rhs)
    { return __lhs.compare(__rhs) == 0; }

  // operator !=
  /**
   *  @brief  Test difference of two strings.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs.compare(@a __rhs) != 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return !(__lhs == __rhs); }

  /**
   *  @brief  Test difference of C string and string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __rhs.compare(@a __lhs) != 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator!=(const _CharT* __lhs,
	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return !(__lhs == __rhs); }

  /**
   *  @brief  Test difference of string and C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs.compare(@a __rhs) != 0.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator!=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	       const _CharT* __rhs)
    { return !(__lhs == __rhs); }

  // operator <
  /**
   *  @brief  Test if string precedes string.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs precedes @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __lhs.compare(__rhs) < 0; }

  /**
   *  @brief  Test if string precedes C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs precedes @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator<(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	      const _CharT* __rhs)
    { return __lhs.compare(__rhs) < 0; }

  /**
   *  @brief  Test if C string precedes string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __lhs precedes @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator<(const _CharT* __lhs,
	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __rhs.compare(__lhs) > 0; }

  // operator >
  /**
   *  @brief  Test if string follows string.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs follows @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __lhs.compare(__rhs) > 0; }

  /**
   *  @brief  Test if string follows C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs follows @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator>(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	      const _CharT* __rhs)
    { return __lhs.compare(__rhs) > 0; }

  /**
   *  @brief  Test if C string follows string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __lhs follows @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator>(const _CharT* __lhs,
	      const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __rhs.compare(__lhs) < 0; }

  // operator <=
  /**
   *  @brief  Test if string doesn't follow string.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs doesn't follow @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __lhs.compare(__rhs) <= 0; }

  /**
   *  @brief  Test if string doesn't follow C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs doesn't follow @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator<=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	       const _CharT* __rhs)
    { return __lhs.compare(__rhs) <= 0; }

  /**
   *  @brief  Test if C string doesn't follow string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __lhs doesn't follow @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator<=(const _CharT* __lhs,
	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __rhs.compare(__lhs) >= 0; }

  // operator >=
  /**
   *  @brief  Test if string doesn't precede string.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *  @return  True if @a __lhs doesn't precede @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __lhs.compare(__rhs) >= 0; }

  /**
   *  @brief  Test if string doesn't precede C string.
   *  @param __lhs  String.
   *  @param __rhs  C string.
   *  @return  True if @a __lhs doesn't precede @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator>=(const __versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	       const _CharT* __rhs)
    { return __lhs.compare(__rhs) >= 0; }

  /**
   *  @brief  Test if C string doesn't precede string.
   *  @param __lhs  C string.
   *  @param __rhs  String.
   *  @return  True if @a __lhs doesn't precede @a __rhs.  False otherwise.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline bool
    operator>=(const _CharT* __lhs,
	       const __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { return __rhs.compare(__lhs) <= 0; }

  /**
   *  @brief  Swap contents of two strings.
   *  @param __lhs  First string.
   *  @param __rhs  Second string.
   *
   *  Exchanges the contents of @a __lhs and @a __rhs in constant time.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline void
    swap(__versa_string<_CharT, _Traits, _Alloc, _Base>& __lhs,
	 __versa_string<_CharT, _Traits, _Alloc, _Base>& __rhs)
    { __lhs.swap(__rhs); }

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   *  @brief  Read stream into a string.
   *  @param __is  Input stream.
   *  @param __str  Buffer to store into.
   *  @return  Reference to the input stream.
   *
   *  Stores characters from @a __is into @a __str until whitespace is
   *  found, the end of the stream is encountered, or str.max_size()
   *  is reached.  If is.width() is non-zero, that is the limit on the
   *  number of characters stored into @a __str.  Any previous
   *  contents of @a __str are erased.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
    basic_istream<_CharT, _Traits>&
    operator>>(basic_istream<_CharT, _Traits>& __is,
	       __gnu_cxx::__versa_string<_CharT, _Traits,
	                                 _Alloc, _Base>& __str);

  /**
   *  @brief  Write string to a stream.
   *  @param __os  Output stream.
   *  @param __str  String to write out.
   *  @return  Reference to the output stream.
   *
   *  Output characters of @a __str into os following the same rules as for
   *  writing a C string.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
	   template <typename, typename, typename> class _Base>
    inline basic_ostream<_CharT, _Traits>&
    operator<<(basic_ostream<_CharT, _Traits>& __os,
	       const __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc,
	       _Base>& __str)
    {
      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 586. string inserter not a formatted function
      return __ostream_insert(__os, __str.data(), __str.size());
    }

  /**
   *  @brief  Read a line from stream into a string.
   *  @param __is  Input stream.
   *  @param __str  Buffer to store into.
   *  @param __delim  Character marking end of line.
   *  @return  Reference to the input stream.
   *
   *  Stores characters from @a __is into @a __str until @a __delim is
   *  found, the end of the stream is encountered, or str.max_size()
   *  is reached.  If is.width() is non-zero, that is the limit on the
   *  number of characters stored into @a __str.  Any previous
   *  contents of @a __str are erased.  If @a delim was encountered,
   *  it is extracted but not stored into @a __str.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
    basic_istream<_CharT, _Traits>&
    getline(basic_istream<_CharT, _Traits>& __is,
	    __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str,
	    _CharT __delim);

  /**
   *  @brief  Read a line from stream into a string.
   *  @param __is  Input stream.
   *  @param __str  Buffer to store into.
   *  @return  Reference to the input stream.
   *
   *  Stores characters from is into @a __str until &apos;\n&apos; is
   *  found, the end of the stream is encountered, or str.max_size()
   *  is reached.  If is.width() is non-zero, that is the limit on the
   *  number of characters stored into @a __str.  Any previous
   *  contents of @a __str are erased.  If end of line was
   *  encountered, it is extracted but not stored into @a __str.
   */
  template<typename _CharT, typename _Traits, typename _Alloc,
           template <typename, typename, typename> class _Base>
    inline basic_istream<_CharT, _Traits>&
    getline(basic_istream<_CharT, _Traits>& __is,
	    __gnu_cxx::__versa_string<_CharT, _Traits, _Alloc, _Base>& __str)
    { return getline(__is, __str, __is.widen('\n')); }      

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#if __cplusplus >= 201103L

#include <ext/string_conversions.h>

namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

#if _GLIBCXX_USE_C99_STDLIB
  // 21.4 Numeric Conversions [string.conversions].
  inline int
  stoi(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa<long, int>(&std::strtol, "stoi", __str.c_str(),
					__idx, __base); }

  inline long
  stol(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtol, "stol", __str.c_str(),
			     __idx, __base); }

  inline unsigned long
  stoul(const __vstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoul, "stoul", __str.c_str(),
			     __idx, __base); }

  inline long long
  stoll(const __vstring& __str, std::size_t* __idx = 0,	int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoll, "stoll", __str.c_str(),
			     __idx, __base); }

  inline unsigned long long
  stoull(const __vstring& __str, std::size_t* __idx, int __base = 10)
  { return __gnu_cxx::__stoa(&std::strtoull, "stoull", __str.c_str(),
			     __idx, __base); }

  // NB: strtof vs strtod.
  inline float
  stof(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtof, "stof", __str.c_str(), __idx); }

  inline double
  stod(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtod, "stod", __str.c_str(), __idx); }

  inline long double
  stold(const __vstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::strtold, "stold", __str.c_str(), __idx); }
#endif // _GLIBCXX_USE_C99_STDLIB

#if _GLIBCXX_USE_C99_STDIO
  // NB: (v)snprintf vs sprintf.

  // DR 1261.
  inline __vstring
  to_string(int __val)
  { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, 4 * sizeof(int),
					      "%d", __val); }

  inline __vstring
  to_string(unsigned __val)
  { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf,
					      4 * sizeof(unsigned),
					      "%u", __val); }

  inline __vstring
  to_string(long __val)
  { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf,
					      4 * sizeof(long),
					      "%ld", __val); }

  inline __vstring
  to_string(unsigned long __val)
  { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf,
					      4 * sizeof(unsigned long),
					      "%lu", __val); }


  inline __vstring
  to_string(long long __val)
  { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf,
					      4 * sizeof(long long),
					      "%lld", __val); }

  inline __vstring
  to_string(unsigned long long __val)
  { return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf,
					      4 * sizeof(unsigned long long),
					      "%llu", __val); }

  inline __vstring
  to_string(float __val)
  {
    const int __n = __numeric_traits<float>::__max_exponent10 + 20;
    return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, __n,
					      "%f", __val);
  }

  inline __vstring
  to_string(double __val)
  {
    const int __n = __numeric_traits<double>::__max_exponent10 + 20;
    return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, __n,
					      "%f", __val);
  }

  inline __vstring
  to_string(long double __val)
  {
    const int __n = __numeric_traits<long double>::__max_exponent10 + 20;
    return __gnu_cxx::__to_xstring<__vstring>(&std::vsnprintf, __n,
					      "%Lf", __val);
  }
#endif // _GLIBCXX_USE_C99_STDIO

#if defined(_GLIBCXX_USE_WCHAR_T) && _GLIBCXX_USE_C99_WCHAR
  inline int 
  stoi(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa<long, int>(&std::wcstol, "stoi", __str.c_str(),
					__idx, __base); }

  inline long 
  stol(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::wcstol, "stol", __str.c_str(),
			     __idx, __base); }

  inline unsigned long
  stoul(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::wcstoul, "stoul", __str.c_str(),
			     __idx, __base); }

  inline long long
  stoll(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::wcstoll, "stoll", __str.c_str(),
			     __idx, __base); }

  inline unsigned long long
  stoull(const __wvstring& __str, std::size_t* __idx = 0, int __base = 10)
  { return __gnu_cxx::__stoa(&std::wcstoull, "stoull", __str.c_str(),
			     __idx, __base); }

  // NB: wcstof vs wcstod.
  inline float
  stof(const __wvstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::wcstof, "stof", __str.c_str(), __idx); }

  inline double
  stod(const __wvstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::wcstod, "stod", __str.c_str(), __idx); }

  inline long double
  stold(const __wvstring& __str, std::size_t* __idx = 0)
  { return __gnu_cxx::__stoa(&std::wcstold, "stold", __str.c_str(), __idx); }

#ifndef _GLIBCXX_HAVE_BROKEN_VSWPRINTF
  // DR 1261.
  inline __wvstring
  to_wstring(int __val)
  { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf,
					       4 * sizeof(int),
					       L"%d", __val); }

  inline __wvstring
  to_wstring(unsigned __val)
  { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf,
					       4 * sizeof(unsigned),
					       L"%u", __val); }

  inline __wvstring
  to_wstring(long __val)
  { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf,
					       4 * sizeof(long),
					       L"%ld", __val); }

  inline __wvstring
  to_wstring(unsigned long __val)
  { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf,
					       4 * sizeof(unsigned long),
					       L"%lu", __val); }

  inline __wvstring
  to_wstring(long long __val)
  { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf,
					       4 * sizeof(long long),
					       L"%lld", __val); }

  inline __wvstring
  to_wstring(unsigned long long __val)
  { return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf,
					       4 * sizeof(unsigned long long),
					       L"%llu", __val); }

  inline __wvstring
  to_wstring(float __val)
  {
    const int __n = __numeric_traits<float>::__max_exponent10 + 20;
    return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, __n,
					       L"%f", __val);
  }

  inline __wvstring
  to_wstring(double __val)
  {
    const int __n = __numeric_traits<double>::__max_exponent10 + 20;
    return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, __n,
					       L"%f", __val);
  }

  inline __wvstring
  to_wstring(long double __val)
  {
    const int __n = __numeric_traits<long double>::__max_exponent10 + 20;
    return __gnu_cxx::__to_xstring<__wvstring>(&std::vswprintf, __n,
					       L"%Lf", __val);
  }
#endif // _GLIBCXX_HAVE_BROKEN_VSWPRINTF
#endif // _GLIBCXX_USE_WCHAR_T && _GLIBCXX_USE_C99_WCHAR

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif

#if __cplusplus >= 201103L

#include <bits/functional_hash.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /// std::hash specialization for __vstring.
  template<>
    struct hash<__gnu_cxx::__vstring>
    : public __hash_base<size_t, __gnu_cxx::__vstring>
    {
      size_t
      operator()(const __gnu_cxx::__vstring& __s) const noexcept
      { return std::_Hash_impl::hash(__s.data(), __s.length()); }
    };

  /// std::hash specialization for __wvstring.
  template<>
    struct hash<__gnu_cxx::__wvstring>
    : public __hash_base<size_t, __gnu_cxx::__wvstring>
    {
      size_t
      operator()(const __gnu_cxx::__wvstring& __s) const noexcept
      { return std::_Hash_impl::hash(__s.data(),
                                     __s.length() * sizeof(wchar_t)); }
    };

  /// std::hash specialization for __u16vstring.
  template<>
    struct hash<__gnu_cxx::__u16vstring>
    : public __hash_base<size_t, __gnu_cxx::__u16vstring>
    {
      size_t
      operator()(const __gnu_cxx::__u16vstring& __s) const noexcept
      { return std::_Hash_impl::hash(__s.data(),
                                     __s.length() * sizeof(char16_t)); }
    };

  /// std::hash specialization for __u32vstring.
  template<>
    struct hash<__gnu_cxx::__u32vstring>
    : public __hash_base<size_t, __gnu_cxx::__u32vstring>
    {
      size_t
      operator()(const __gnu_cxx::__u32vstring& __s) const noexcept
      { return std::_Hash_impl::hash(__s.data(),
                                     __s.length() * sizeof(char32_t)); }
    };

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#endif // C++11

#include <ext/vstring.tcc>

#endif /* _VSTRING_H */
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        author692 __UNIQUE_ID_license691 __UNIQUE_ID___addressable_cleanup_module690 __UNIQUE_ID___addressable_init_module689 .LC0 ipvlan_register_nf_hook ipvlan_netid ipvl_nfops ipvlan_skb_to_addr ipvlan_nf_input ipvlan_ns_exit ipvlan_l3_rcv ipvlan_unregister_nf_hook ipvlan_net_ops ipvl_l3mdev_ops __already_done.1 __already_done.0 __do_once_done ip6_route_input_lookup ida_alloc_range netdev_increment_features dev_pre_changeaddr_notify dev_mc_sync ida_destroy netdev_is_rx_handler_busy __rcu_read_lock ipvlan_get_L3_hdr rtnl_is_locked netdev_update_features consume_skb ip6_local_out __this_module queue_work_on ipvlan_l3s_unregister dev_uc_sync this_cpu_off rtnl_link_register netif_inherit_tso_max eth_header_cache kfree ip_route_output_flow ipvlan_find_addr unregister_netdevice_queue ipvlan_migrate_l3s_hook __per_cpu_offset _raw_spin_lock dev_uc_unsync ether_setup netdev_err __fentry__ netdev_upper_dev_link dev_addr_mod netdev_core_stats_alloc __x86_indirect_thunk_rax ipvlan_ht_addr_del do_trace_netlink_extack ___ratelimit netdev_rx_handler_unregister eth_header_parse __stack_chk_fail _raw_spin_unlock_bh eth_header_cache_update nf_register_net_hooks ip6_route_output_flags unregister_inetaddr_notifier ipvlan_addr_lookup ip_route_input_noref __alloc_percpu_gfp ipvlan_queue_xmit __list_add_valid __dev_get_by_index rtnl_link_unregister skb_pull __rcu_read_unlock netif_stacked_transfer_operstate kfree_skb_reason netdev_upper_dev_unlink nla_put ida_free _find_next_bit ns_capable nf_unregister_net_hooks __list_del_entry_valid __local_bh_enable_ip ethtool_op_get_link __ethtool_get_link_ksettings unregister_netdevice_many unregister_pernet_subsys __cpu_possible_mask __x86_return_thunk unregister_inet6addr_notifier nr_cpu_ids __pskb_pull_tail netif_rx unregister_netdevice_notifier free_percpu ipvlan_init_secret ipvlan_handle_frame skb_scrub_packet strscpy __preempt_count unregister_inet6addr_validator_notifier __dev_queue_xmit kvfree_call_rcu vlan_vid_add ipvlan_l3s_cleanup call_netdevice_notifiers vlan_vid_del dev_set_allmulti ipvlan_l3s_init __dynamic_pr_debug cancel_work_sync __warn_printk skb_clone _raw_spin_lock_bh dst_release __SCT__cond_resched ipvlan_process_multicast netdev_rx_handler_register unregister_inetaddr_validator_notifier get_random_bytes ip_local_out ipvlan_l3s_register kmalloc_trace dev_mc_unsync _raw_spin_unlock dev_change_flags ipvlan_ht_addr_add dev_forward_skb kmalloc_caches __do_once_start ipvlan_mac_hash ipvlan_addr_busy system_wq register_netdevice                               '             0             A                          C            H            O            a                                                                       +            0            A            G                                                            &            K            [            s                                                a                                                            "            ?            Q                                 	                                                                                      p                	                                                          U                        A            g            q                                    	            !	            @	            j	            t	            	            	            	            	            	            
                        G            q                                                            c            q                        
            
           
            -            7            n                                                                        /            7            ^            p                                                                                                            V            [            a                        5            m                                             	               @                                    	                (            L                                                                                                    "            N            i            {                                            @                                                
                       8            f            z                                                                        @         	   T            u                                                                                     	   "            9            O            ^            q                                                                                                                                                2            <            C            Q            d            q                                                                                                            8            =            Q            _            u                                                                                                                                    M            h            z                                                                                    V            s            }                                                            )            I            {                                 	               x                                   	                           
            !            S                                                *                                      *                    <                   K                   S            [            4                                          @                                                             >             N             X                                                                       !            `      !                   !            !!            -!            A!            U!            =       Z!            k!            D       p!            !            !                  !                   !                   !            !      !                   !            !            "            2"            Q"            d"            q"            "                    #            a#            #            #            $            I$            v$            ~$            $            	%             %            1%            C%                  i%            p%            ~%           %            %                   %            %                   %            %            %                  %             &            &            &            +&            `       0&            <&            `       G&            Q&            &            &            '           :'           q'            '            '            '                    '                    (            (            3(            A(            M(                   h(            (            (            (            )            ,)            Z)            c)            )            )            )            )            *            *            1*            *            *                    *            *            *                    *            +            +                    (+            \       7+            q+                    
,                    #,            S,            _,            w,            ,            ,            ,            ,            ,            -            -            --            A-            i-                  -            -            -           .            9.            M       A.            H.            Q.            l.                  .            .            .            .           /             /            u       (/            1/            8/                   A/            Q/            g/            s/            `      {/            /            /            /                    /            0            0            $0            10            x0            0            0            0                   0            0            0            0            `      0            0            ^1            1            ;2            ]2            m2            2            2                   2            2            2            2            `      2            2            2            2            2                   2            3            3            93         	          H3            P      O3            p      U3         	          [3            q3            x3            `      }3            3            3            `      3            3            3            3                  3            3         	           4            P      4            p      4         	           4            !4            .4            X4            ^4         	   m4            P      t4            p      z4         	   4            
             (                                 `      "                    *             4                   ;             "       H             M                   `                    h             p             u             ".                                                                 /                                             P                                 0                    &                    +             2                    7             >             p       C             H             S                    Z                    ^                   e                    i                    p                    t                    {                                 !                                                                                                                                          p                                 0                                                                  P                                                                  
                          P                                         %             ,             p       1             8             0       =             D                    I                                                                                                            3                     4                                          0                      1           $                     (          9           ,          :           0                    4          6           8          7           0            @!      X                  `                  p                                 !      `                  h                    p                    x                                0*                                                                        P                                    P&      @            '      `                  h                  X            p                  p      `            00                  00                  0                                         @                    `                   @                          (                   0             P      8                   @             @      H             p      P              	      X             	      `                   h             p      p                   x                                `                                      p                                                                                                                   P             // The template and inlines for the numeric_limits classes. -*- C++ -*-

// Copyright (C) 1999-2022 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 include/limits
 *  This is a Standard C++ Library header.
 */

// Note: this is not a conforming implementation.
// Written by Gabriel Dos Reis <gdr@codesourcery.com>

//
// ISO 14882:1998
// 18.2.1
//

#ifndef _GLIBCXX_NUMERIC_LIMITS
#define _GLIBCXX_NUMERIC_LIMITS 1

#pragma GCC system_header

#include <bits/c++config.h>

//
// The numeric_limits<> traits document implementation-defined aspects
// of fundamental arithmetic data types (integers and floating points).
// From Standard C++ point of view, there are 14 such types:
//   * integers
//         bool							(1)
//         char, signed char, unsigned char, wchar_t            (4)
//         short, unsigned short				(2)
//         int, unsigned					(2)
//         long, unsigned long					(2)
//
//   * floating points
//         float						(1)
//         double						(1)
//         long double						(1)
//
// GNU C++ understands (where supported by the host C-library)
//   * integer
//         long long, unsigned long long			(2)
//
// which brings us to 16 fundamental arithmetic data types in GNU C++.
//
//
// Since a numeric_limits<> is a bit tricky to get right, we rely on
// an interface composed of macros which should be defined in config/os
// or config/cpu when they differ from the generic (read arbitrary)
// definitions given here.
//

// These values can be overridden in the target configuration file.
// The default values are appropriate for many 32-bit targets.

// GCC only intrinsically supports modulo integral types.  The only remaining
// integral exceptional values is division by zero.  Only targets that do not
// signal division by zero in some "hard to ignore" way should use false.
#ifndef __glibcxx_integral_traps
# define __glibcxx_integral_traps true
#endif

// float
//

// Default values.  Should be overridden in configuration files if necessary.

#ifndef __glibcxx_float_has_denorm_loss
#  define __glibcxx_float_has_denorm_loss false
#endif
#ifndef __glibcxx_float_traps
#  define __glibcxx_float_traps false
#endif
#ifndef __glibcxx_float_tinyness_before
#  define __glibcxx_float_tinyness_before false
#endif

// double

// Default values.  Should be overridden in configuration files if necessary.

#ifndef __glibcxx_double_has_denorm_loss
#  define __glibcxx_double_has_denorm_loss false
#endif
#ifndef __glibcxx_double_traps
#  define __glibcxx_double_traps false
#endif
#ifndef __glibcxx_double_tinyness_before
#  define __glibcxx_double_tinyness_before false
#endif

// long double

// Default values.  Should be overridden in configuration files if necessary.

#ifndef __glibcxx_long_double_has_denorm_loss
#  define __glibcxx_long_double_has_denorm_loss false
#endif
#ifndef __glibcxx_long_double_traps
#  define __glibcxx_long_double_traps false
#endif
#ifndef __glibcxx_long_double_tinyness_before
#  define __glibcxx_long_double_tinyness_before false
#endif

// You should not need to define any macros below this point.

#define __glibcxx_signed_b(T,B)	((T)(-1) < 0)

#define __glibcxx_min_b(T,B)					\
  (__glibcxx_signed_b (T,B) ? -__glibcxx_max_b (T,B) - 1 : (T)0)

#define __glibcxx_max_b(T,B)						\
  (__glibcxx_signed_b (T,B) ?						\
   (((((T)1 << (__glibcxx_digits_b (T,B) - 1)) - 1) << 1) + 1) : ~(T)0)

#define __glibcxx_digits_b(T,B)				\
  (B - __glibcxx_signed_b (T,B))

// The fraction 643/2136 approximates log10(2) to 7 significant digits.
#define __glibcxx_digits10_b(T,B)		\
  (__glibcxx_digits_b (T,B) * 643L / 2136)

#define __glibcxx_signed(T) \
  __glibcxx_signed_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_min(T) \
  __glibcxx_min_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_max(T) \
  __glibcxx_max_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_digits(T) \
  __glibcxx_digits_b (T, sizeof(T) * __CHAR_BIT__)
#define __glibcxx_digits10(T) \
  __glibcxx_digits10_b (T, sizeof(T) * __CHAR_BIT__)

#define __glibcxx_max_digits10(T) \
  (2 + (T) * 643L / 2136)

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION

  /**
   *  @brief Describes the rounding style for floating-point types.
   *
   *  This is used in the std::numeric_limits class.
  */
  enum float_round_style
  {
    round_indeterminate       = -1,    /// Intermediate.
    round_toward_zero         = 0,     /// To zero.
    round_to_nearest          = 1,     /// To the nearest representable value.
    round_toward_infinity     = 2,     /// To infinity.
    round_toward_neg_infinity = 3      /// To negative infinity.
  };

  /**
   *  @brief Describes the denormalization for floating-point types.
   *
   *  These values represent the presence or absence of a variable number
   *  of exponent bits.  This type is used in the std::numeric_limits class.
  */
  enum float_denorm_style
  {
    /// Indeterminate at compile time whether denormalized values are allowed.
    denorm_indeterminate = -1,
    /// The type does not allow denormalized values.
    denorm_absent        = 0,
    /// The type allows denormalized values.
    denorm_present       = 1
  };

  /**
   *  @brief Part of std::numeric_limits.
   *
   *  The @c static @c const members are usable as integral constant
   *  expressions.
   *
   *  @note This is a separate class for purposes of efficiency; you
   *        should only access these members as part of an instantiation
   *        of the std::numeric_limits class.
  */
  struct __numeric_limits_base
  {
    /** This will be true for all fundamental types (which have
	specializations), and false for everything else.  */
    static _GLIBCXX_USE_CONSTEXPR bool is_specialized = false;

    /** The number of @c radix digits that be represented without change:  for
	integer types, the number of non-sign bits in the mantissa; for
	floating types, the number of @c radix digits in the mantissa.  */
    static _GLIBCXX_USE_CONSTEXPR int digits = 0;

    /** The number of base 10 digits that can be represented without change. */
    static _GLIBCXX_USE_CONSTEXPR int digits10 = 0;

#if __cplusplus >= 201103L
    /** The number of base 10 digits required to ensure that values which
	differ are always differentiated.  */
    static constexpr int max_digits10 = 0;
#endif

    /** True if the type is signed.  */
    static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;

    /** True if the type is integer.  */
    static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;

    /** True if the type uses an exact representation. All integer types are
	exact, but not all exact types are integer.  For example, rational and
	fixed-exponent representations are exact but not integer. */
    static _GLIBCXX_USE_CONSTEXPR bool is_exact = false;

    /** For integer types, specifies the base of the representation.  For
	floating types, specifies the base of the exponent representation.  */
    static _GLIBCXX_USE_CONSTEXPR int radix = 0;

    /** The minimum negative integer such that @c radix raised to the power of
	(one less than that integer) is a normalized floating point number.  */
    static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;

    /** The minimum negative integer such that 10 raised to that power is in
	the range of normalized floating point numbers.  */
    static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;

    /** The maximum positive integer such that @c radix raised to the power of
	(one less than that integer) is a representable finite floating point
	number.  */
    static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;

    /** The maximum positive integer such that 10 raised to that power is in
	the range of representable finite floating point numbers.  */
    static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

    /** True if the type has a representation for positive infinity.  */
    static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;

    /** True if the type has a representation for a quiet (non-signaling)
	Not a Number.  */
    static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;

    /** True if the type has a representation for a signaling
	Not a Number.  */
    static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;

    /** See std::float_denorm_style for more information.  */
    static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm = denorm_absent;

    /** True if loss of accuracy is detected as a denormalization loss,
	rather than as an inexact result. */
    static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

    /** True if-and-only-if the type adheres to the IEC 559 standard, also
	known as IEEE 754.  (Only makes sense for floating point types.)  */
    static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;

    /** True if the set of values representable by the type is
	finite.  All built-in types are bounded, this member would be
	false for arbitrary precision types. */
    static _GLIBCXX_USE_CONSTEXPR bool is_bounded = false;

    /** True if the type is @e modulo. A type is modulo if, for any
	operation involving +, -, or * on values of that type whose
	result would fall outside the range [min(),max()], the value
	returned differs from the true value by an integer multiple of
	max() - min() + 1. On most machines, this is false for floating
	types, true for unsigned integers, and true for signed integers.
	See PR22200 about signed integers.  */
    static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

    /** True if trapping is implemented for this type.  */
    static _GLIBCXX_USE_CONSTEXPR bool traps = false;

    /** True if tininess is detected before rounding.  (see IEC 559)  */
    static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;

    /** See std::float_round_style for more information.  This is only
	meaningful for floating types; integer types will all be
	round_toward_zero.  */
    static _GLIBCXX_USE_CONSTEXPR float_round_style round_style =
						    round_toward_zero;
  };

  /**
   *  @brief Properties of fundamental types.
   *
   *  This class allows a program to obtain information about the
   *  representation of a fundamental type on a given platform.  For
   *  non-fundamental types, the functions will return 0 and the data
   *  members will all be @c false.
  */
  template<typename _Tp>
    struct numeric_limits : public __numeric_limits_base
    {
      /** The minimum finite value, or for floating types with
	  denormalization, the minimum positive normalized value.  */
      static _GLIBCXX_CONSTEXPR _Tp
      min() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }

      /** The maximum finite value.  */
      static _GLIBCXX_CONSTEXPR _Tp
      max() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }

#if __cplusplus >= 201103L
      /** A finite value x such that there is no other finite value y
       *  where y < x.  */
      static constexpr _Tp
      lowest() noexcept { return _Tp(); }
#endif

      /** The @e machine @e epsilon:  the difference between 1 and the least
	  value greater than 1 that is representable.  */
      static _GLIBCXX_CONSTEXPR _Tp
      epsilon() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }

      /** The maximum rounding error measurement (see LIA-1).  */
      static _GLIBCXX_CONSTEXPR _Tp
      round_error() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }

      /** The representation of positive infinity, if @c has_infinity.  */
      static _GLIBCXX_CONSTEXPR _Tp
      infinity() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }

      /** The representation of a quiet Not a Number,
	  if @c has_quiet_NaN. */
      static _GLIBCXX_CONSTEXPR _Tp
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }

      /** The representation of a signaling Not a Number, if
	  @c has_signaling_NaN. */
      static _GLIBCXX_CONSTEXPR _Tp
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }

      /** The minimum positive denormalized value.  For types where
	  @c has_denorm is false, this is the minimum positive normalized
	  value.  */
      static _GLIBCXX_CONSTEXPR _Tp
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return _Tp(); }
    };

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 559. numeric_limits<const T>

  template<typename _Tp>
    struct numeric_limits<const _Tp>
    : public numeric_limits<_Tp> { };

  template<typename _Tp>
    struct numeric_limits<volatile _Tp>
    : public numeric_limits<_Tp> { };

  template<typename _Tp>
    struct numeric_limits<const volatile _Tp>
    : public numeric_limits<_Tp> { };

  // Now there follow 16 explicit specializations.  Yes, 16.  Make sure
  // you get the count right. (18 in C++11 mode, with char16_t and char32_t.)
  // (+1 if char8_t is enabled.)

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 184. numeric_limits<bool> wording problems

  /// numeric_limits<bool> specialization.
  template<>
    struct numeric_limits<bool>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR bool
      min() _GLIBCXX_USE_NOEXCEPT { return false; }

      static _GLIBCXX_CONSTEXPR bool
      max() _GLIBCXX_USE_NOEXCEPT { return true; }

#if __cplusplus >= 201103L
      static constexpr bool
      lowest() noexcept { return min(); }
#endif
      static _GLIBCXX_USE_CONSTEXPR int digits = 1;
      static _GLIBCXX_USE_CONSTEXPR int digits10 = 0;
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR bool
      epsilon() _GLIBCXX_USE_NOEXCEPT { return false; }

      static _GLIBCXX_CONSTEXPR bool
      round_error() _GLIBCXX_USE_NOEXCEPT { return false; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR bool
      infinity() _GLIBCXX_USE_NOEXCEPT { return false; }

      static _GLIBCXX_CONSTEXPR bool
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return false; }

      static _GLIBCXX_CONSTEXPR bool
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return false; }

      static _GLIBCXX_CONSTEXPR bool
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return false; }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      // It is not clear what it means for a boolean type to trap.
      // This is a DR on the LWG issue list.  Here, I use integer
      // promotion semantics.
      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<char> specialization.
  template<>
    struct numeric_limits<char>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR char
      min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min(char); }

      static _GLIBCXX_CONSTEXPR char
      max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max(char); }

#if __cplusplus >= 201103L
      static constexpr char
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __glibcxx_digits (char);
      static _GLIBCXX_USE_CONSTEXPR int digits10 = __glibcxx_digits10 (char);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = __glibcxx_signed (char);
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR char
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR char
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR
      char infinity() _GLIBCXX_USE_NOEXCEPT { return char(); }

      static _GLIBCXX_CONSTEXPR char
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return char(); }

      static _GLIBCXX_CONSTEXPR char
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return char(); }

      static _GLIBCXX_CONSTEXPR char
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return static_cast<char>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = !is_signed;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<signed char> specialization.
  template<>
    struct numeric_limits<signed char>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR signed char
      min() _GLIBCXX_USE_NOEXCEPT { return -__SCHAR_MAX__ - 1; }

      static _GLIBCXX_CONSTEXPR signed char
      max() _GLIBCXX_USE_NOEXCEPT { return __SCHAR_MAX__; }

#if __cplusplus >= 201103L
      static constexpr signed char
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __glibcxx_digits (signed char);
      static _GLIBCXX_USE_CONSTEXPR int digits10
       = __glibcxx_digits10 (signed char);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR signed char
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR signed char
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR signed char
      infinity() _GLIBCXX_USE_NOEXCEPT { return static_cast<signed char>(0); }

      static _GLIBCXX_CONSTEXPR signed char
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return static_cast<signed char>(0); }

      static _GLIBCXX_CONSTEXPR signed char
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<signed char>(0); }

      static _GLIBCXX_CONSTEXPR signed char
      denorm_min() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<signed char>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<unsigned char> specialization.
  template<>
    struct numeric_limits<unsigned char>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR unsigned char
      min() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned char
      max() _GLIBCXX_USE_NOEXCEPT { return __SCHAR_MAX__ * 2U + 1; }

#if __cplusplus >= 201103L
      static constexpr unsigned char
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits
       = __glibcxx_digits (unsigned char);
      static _GLIBCXX_USE_CONSTEXPR int digits10
       = __glibcxx_digits10 (unsigned char);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR unsigned char
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned char
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR unsigned char
      infinity() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned char>(0); }

      static _GLIBCXX_CONSTEXPR unsigned char
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned char>(0); }

      static _GLIBCXX_CONSTEXPR unsigned char
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned char>(0); }

      static _GLIBCXX_CONSTEXPR unsigned char
      denorm_min() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned char>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<wchar_t> specialization.
  template<>
    struct numeric_limits<wchar_t>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR wchar_t
      min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min (wchar_t); }

      static _GLIBCXX_CONSTEXPR wchar_t
      max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (wchar_t); }

#if __cplusplus >= 201103L
      static constexpr wchar_t
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __glibcxx_digits (wchar_t);
      static _GLIBCXX_USE_CONSTEXPR int digits10
       = __glibcxx_digits10 (wchar_t);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = __glibcxx_signed (wchar_t);
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR wchar_t
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR wchar_t
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR wchar_t
      infinity() _GLIBCXX_USE_NOEXCEPT { return wchar_t(); }

      static _GLIBCXX_CONSTEXPR wchar_t
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return wchar_t(); }

      static _GLIBCXX_CONSTEXPR wchar_t
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return wchar_t(); }

      static _GLIBCXX_CONSTEXPR wchar_t
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return wchar_t(); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = !is_signed;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

#if _GLIBCXX_USE_CHAR8_T
  /// numeric_limits<char8_t> specialization.
  template<>
    struct numeric_limits<char8_t>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR char8_t
      min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min (char8_t); }

      static _GLIBCXX_CONSTEXPR char8_t
      max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max (char8_t); }

      static _GLIBCXX_CONSTEXPR char8_t
      lowest() _GLIBCXX_USE_NOEXCEPT { return min(); }

      static _GLIBCXX_USE_CONSTEXPR int digits = __glibcxx_digits (char8_t);
      static _GLIBCXX_USE_CONSTEXPR int digits10 = __glibcxx_digits10 (char8_t);
      static _GLIBCXX_USE_CONSTEXPR int max_digits10 = 0;
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = __glibcxx_signed (char8_t);
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR char8_t
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR char8_t
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
	= denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR char8_t
      infinity() _GLIBCXX_USE_NOEXCEPT { return char8_t(); }

      static _GLIBCXX_CONSTEXPR char8_t
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return char8_t(); }

      static _GLIBCXX_CONSTEXPR char8_t
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return char8_t(); }

      static _GLIBCXX_CONSTEXPR char8_t
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return char8_t(); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = !is_signed;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
	= round_toward_zero;
    };
#endif

#if __cplusplus >= 201103L
  /// numeric_limits<char16_t> specialization.
  template<>
    struct numeric_limits<char16_t>
    {
      static constexpr bool is_specialized = true;

      static constexpr char16_t
      min() noexcept { return __glibcxx_min (char16_t); }

      static constexpr char16_t
      max() noexcept { return __glibcxx_max (char16_t); }

      static constexpr char16_t
      lowest() noexcept { return min(); }

      static constexpr int digits = __glibcxx_digits (char16_t);
      static constexpr int digits10 = __glibcxx_digits10 (char16_t);
      static constexpr int max_digits10 = 0;
      static constexpr bool is_signed = __glibcxx_signed (char16_t);
      static constexpr bool is_integer = true;
      static constexpr bool is_exact = true;
      static constexpr int radix = 2;

      static constexpr char16_t
      epsilon() noexcept { return 0; }

      static constexpr char16_t
      round_error() noexcept { return 0; }

      static constexpr int min_exponent = 0;
      static constexpr int min_exponent10 = 0;
      static constexpr int max_exponent = 0;
      static constexpr int max_exponent10 = 0;

      static constexpr bool has_infinity = false;
      static constexpr bool has_quiet_NaN = false;
      static constexpr bool has_signaling_NaN = false;
      static constexpr float_denorm_style has_denorm = denorm_absent;
      static constexpr bool has_denorm_loss = false;

      static constexpr char16_t
      infinity() noexcept { return char16_t(); }

      static constexpr char16_t
      quiet_NaN() noexcept { return char16_t(); }

      static constexpr char16_t
      signaling_NaN() noexcept { return char16_t(); }

      static constexpr char16_t
      denorm_min() noexcept { return char16_t(); }

      static constexpr bool is_iec559 = false;
      static constexpr bool is_bounded = true;
      static constexpr bool is_modulo = !is_signed;

      static constexpr bool traps = __glibcxx_integral_traps;
      static constexpr bool tinyness_before = false;
      static constexpr float_round_style round_style = round_toward_zero;
    };

  /// numeric_limits<char32_t> specialization.
  template<>
    struct numeric_limits<char32_t>
    {
      static constexpr bool is_specialized = true;

      static constexpr char32_t
      min() noexcept { return __glibcxx_min (char32_t); }

      static constexpr char32_t
      max() noexcept { return __glibcxx_max (char32_t); }

      static constexpr char32_t
      lowest() noexcept { return min(); }

      static constexpr int digits = __glibcxx_digits (char32_t);
      static constexpr int digits10 = __glibcxx_digits10 (char32_t);
      static constexpr int max_digits10 = 0;
      static constexpr bool is_signed = __glibcxx_signed (char32_t);
      static constexpr bool is_integer = true;
      static constexpr bool is_exact = true;
      static constexpr int radix = 2;

      static constexpr char32_t
      epsilon() noexcept { return 0; }

      static constexpr char32_t
      round_error() noexcept { return 0; }

      static constexpr int min_exponent = 0;
      static constexpr int min_exponent10 = 0;
      static constexpr int max_exponent = 0;
      static constexpr int max_exponent10 = 0;

      static constexpr bool has_infinity = false;
      static constexpr bool has_quiet_NaN = false;
      static constexpr bool has_signaling_NaN = false;
      static constexpr float_denorm_style has_denorm = denorm_absent;
      static constexpr bool has_denorm_loss = false;

      static constexpr char32_t
      infinity() noexcept { return char32_t(); }

      static constexpr char32_t
      quiet_NaN() noexcept { return char32_t(); }

      static constexpr char32_t
      signaling_NaN() noexcept { return char32_t(); }

      static constexpr char32_t
      denorm_min() noexcept { return char32_t(); }

      static constexpr bool is_iec559 = false;
      static constexpr bool is_bounded = true;
      static constexpr bool is_modulo = !is_signed;

      static constexpr bool traps = __glibcxx_integral_traps;
      static constexpr bool tinyness_before = false;
      static constexpr float_round_style round_style = round_toward_zero;
    };
#endif

  /// numeric_limits<short> specialization.
  template<>
    struct numeric_limits<short>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR short
      min() _GLIBCXX_USE_NOEXCEPT { return -__SHRT_MAX__ - 1; }

      static _GLIBCXX_CONSTEXPR short
      max() _GLIBCXX_USE_NOEXCEPT { return __SHRT_MAX__; }

#if __cplusplus >= 201103L
      static constexpr short
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __glibcxx_digits (short);
      static _GLIBCXX_USE_CONSTEXPR int digits10 = __glibcxx_digits10 (short);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR short
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR short
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR short
      infinity() _GLIBCXX_USE_NOEXCEPT { return short(); }

      static _GLIBCXX_CONSTEXPR short
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return short(); }

      static _GLIBCXX_CONSTEXPR short
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return short(); }

      static _GLIBCXX_CONSTEXPR short
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return short(); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<unsigned short> specialization.
  template<>
    struct numeric_limits<unsigned short>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR unsigned short
      min() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned short
      max() _GLIBCXX_USE_NOEXCEPT { return __SHRT_MAX__ * 2U + 1; }

#if __cplusplus >= 201103L
      static constexpr unsigned short
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits
       = __glibcxx_digits (unsigned short);
      static _GLIBCXX_USE_CONSTEXPR int digits10
       = __glibcxx_digits10 (unsigned short);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR unsigned short
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned short
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR unsigned short
      infinity() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned short>(0); }

      static _GLIBCXX_CONSTEXPR unsigned short
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned short>(0); }

      static _GLIBCXX_CONSTEXPR unsigned short
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned short>(0); }

      static _GLIBCXX_CONSTEXPR unsigned short
      denorm_min() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned short>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<int> specialization.
  template<>
    struct numeric_limits<int>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR int
      min() _GLIBCXX_USE_NOEXCEPT { return -__INT_MAX__ - 1; }

      static _GLIBCXX_CONSTEXPR int
      max() _GLIBCXX_USE_NOEXCEPT { return __INT_MAX__; }

#if __cplusplus >= 201103L
      static constexpr int
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __glibcxx_digits (int);
      static _GLIBCXX_USE_CONSTEXPR int digits10 = __glibcxx_digits10 (int);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR int
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR int
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR int
      infinity() _GLIBCXX_USE_NOEXCEPT { return static_cast<int>(0); }

      static _GLIBCXX_CONSTEXPR int
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return static_cast<int>(0); }

      static _GLIBCXX_CONSTEXPR int
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return static_cast<int>(0); }

      static _GLIBCXX_CONSTEXPR int
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return static_cast<int>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<unsigned int> specialization.
  template<>
    struct numeric_limits<unsigned int>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR unsigned int
      min() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned int
      max() _GLIBCXX_USE_NOEXCEPT { return __INT_MAX__ * 2U + 1; }

#if __cplusplus >= 201103L
      static constexpr unsigned int
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits
       = __glibcxx_digits (unsigned int);
      static _GLIBCXX_USE_CONSTEXPR int digits10
       = __glibcxx_digits10 (unsigned int);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR unsigned int
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned int
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR unsigned int
      infinity() _GLIBCXX_USE_NOEXCEPT { return static_cast<unsigned int>(0); }

      static _GLIBCXX_CONSTEXPR unsigned int
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned int>(0); }

      static _GLIBCXX_CONSTEXPR unsigned int
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned int>(0); }

      static _GLIBCXX_CONSTEXPR unsigned int
      denorm_min() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned int>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<long> specialization.
  template<>
    struct numeric_limits<long>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR long
      min() _GLIBCXX_USE_NOEXCEPT { return -__LONG_MAX__ - 1; }

      static _GLIBCXX_CONSTEXPR long
      max() _GLIBCXX_USE_NOEXCEPT { return __LONG_MAX__; }

#if __cplusplus >= 201103L
      static constexpr long
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __glibcxx_digits (long);
      static _GLIBCXX_USE_CONSTEXPR int digits10 = __glibcxx_digits10 (long);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR long
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR long
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR long
      infinity() _GLIBCXX_USE_NOEXCEPT { return static_cast<long>(0); }

      static _GLIBCXX_CONSTEXPR long
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return static_cast<long>(0); }

      static _GLIBCXX_CONSTEXPR long
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return static_cast<long>(0); }

      static _GLIBCXX_CONSTEXPR long
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return static_cast<long>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<unsigned long> specialization.
  template<>
    struct numeric_limits<unsigned long>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR unsigned long
      min() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned long
      max() _GLIBCXX_USE_NOEXCEPT { return __LONG_MAX__ * 2UL + 1; }

#if __cplusplus >= 201103L
      static constexpr unsigned long
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits
       = __glibcxx_digits (unsigned long);
      static _GLIBCXX_USE_CONSTEXPR int digits10
       = __glibcxx_digits10 (unsigned long);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR unsigned long
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned long
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR unsigned long
      infinity() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned long>(0); }

      static _GLIBCXX_CONSTEXPR unsigned long
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned long>(0); }

      static _GLIBCXX_CONSTEXPR unsigned long
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned long>(0); }

      static _GLIBCXX_CONSTEXPR unsigned long
      denorm_min() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned long>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<long long> specialization.
  template<>
    struct numeric_limits<long long>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR long long
      min() _GLIBCXX_USE_NOEXCEPT { return -__LONG_LONG_MAX__ - 1; }

      static _GLIBCXX_CONSTEXPR long long
      max() _GLIBCXX_USE_NOEXCEPT { return __LONG_LONG_MAX__; }

#if __cplusplus >= 201103L
      static constexpr long long
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits
       = __glibcxx_digits (long long);
      static _GLIBCXX_USE_CONSTEXPR int digits10
       = __glibcxx_digits10 (long long);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR long long
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR long long
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR long long
      infinity() _GLIBCXX_USE_NOEXCEPT { return static_cast<long long>(0); }

      static _GLIBCXX_CONSTEXPR long long
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return static_cast<long long>(0); }

      static _GLIBCXX_CONSTEXPR long long
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<long long>(0); }

      static _GLIBCXX_CONSTEXPR long long
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return static_cast<long long>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

  /// numeric_limits<unsigned long long> specialization.
  template<>
    struct numeric_limits<unsigned long long>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR unsigned long long
      min() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned long long
      max() _GLIBCXX_USE_NOEXCEPT { return __LONG_LONG_MAX__ * 2ULL + 1; }

#if __cplusplus >= 201103L
      static constexpr unsigned long long
      lowest() noexcept { return min(); }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits
       = __glibcxx_digits (unsigned long long);
      static _GLIBCXX_USE_CONSTEXPR int digits10
       = __glibcxx_digits10 (unsigned long long);
#if __cplusplus >= 201103L
      static constexpr int max_digits10 = 0;
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;

      static _GLIBCXX_CONSTEXPR unsigned long long
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_CONSTEXPR unsigned long long
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
       = denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;

      static _GLIBCXX_CONSTEXPR unsigned long long
      infinity() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned long long>(0); }

      static _GLIBCXX_CONSTEXPR unsigned long long
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned long long>(0); }

      static _GLIBCXX_CONSTEXPR unsigned long long
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned long long>(0); }

      static _GLIBCXX_CONSTEXPR unsigned long long
      denorm_min() _GLIBCXX_USE_NOEXCEPT
      { return static_cast<unsigned long long>(0); }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_toward_zero;
    };

#define __INT_N(TYPE, BITSIZE, EXT, UEXT)				\
  __extension__								\
  template<>								\
    struct numeric_limits<TYPE>						\
    {									\
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;		\
									\
      static _GLIBCXX_CONSTEXPR TYPE					\
      min() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_min_b (TYPE, BITSIZE); } \
									\
      static _GLIBCXX_CONSTEXPR TYPE					\
      max() _GLIBCXX_USE_NOEXCEPT { return __glibcxx_max_b (TYPE, BITSIZE); } \
									\
      static _GLIBCXX_USE_CONSTEXPR int digits				\
	= BITSIZE - 1;							\
      static _GLIBCXX_USE_CONSTEXPR int digits10			\
	= (BITSIZE - 1) * 643L / 2136;					\
									\
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;		\
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;		\
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;		\
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;			\
									\
      static _GLIBCXX_CONSTEXPR TYPE					\
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }			\
									\
      static _GLIBCXX_CONSTEXPR TYPE 					\
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }			\
									\
      EXT								\
									\
      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;		\
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;		\
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0;		\
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;		\
									\
      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;		\
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;		\
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;	\
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm	\
	= denorm_absent;						\
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;	\
									\
      static _GLIBCXX_CONSTEXPR TYPE					\
      infinity() _GLIBCXX_USE_NOEXCEPT					\
      { return static_cast<TYPE>(0); }					\
									\
      static _GLIBCXX_CONSTEXPR TYPE					\
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT					\
      { return static_cast<TYPE>(0); }					\
									\
      static _GLIBCXX_CONSTEXPR TYPE					\
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT				\
      { return static_cast<TYPE>(0); }					\
									\
      static _GLIBCXX_CONSTEXPR TYPE					\
      denorm_min() _GLIBCXX_USE_NOEXCEPT				\
      { return static_cast<TYPE>(0); }					\
									\
      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false; 		\
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; 		\
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; 		\
									\
      static _GLIBCXX_USE_CONSTEXPR bool traps 				\
	= __glibcxx_integral_traps; 					\
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; 	\
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style 	\
	= round_toward_zero; 						\
    }; 									\
									\
  __extension__								\
  template<>								\
    struct numeric_limits<unsigned TYPE>				\
    {									\
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;		\
									\
      static _GLIBCXX_CONSTEXPR unsigned TYPE				\
      min() _GLIBCXX_USE_NOEXCEPT { return 0; }				\
									\
      static _GLIBCXX_CONSTEXPR unsigned TYPE				\
      max() _GLIBCXX_USE_NOEXCEPT					\
      { return  __glibcxx_max_b (unsigned TYPE, BITSIZE); }		\
									\
      UEXT								\
									\
      static _GLIBCXX_USE_CONSTEXPR int digits				\
	= BITSIZE;							\
      static _GLIBCXX_USE_CONSTEXPR int digits10			\
	= BITSIZE * 643L / 2136; 					\
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = false;		\
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = true;		\
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = true;		\
      static _GLIBCXX_USE_CONSTEXPR int radix = 2;			\
									\
      static _GLIBCXX_CONSTEXPR unsigned TYPE 				\
      epsilon() _GLIBCXX_USE_NOEXCEPT { return 0; }			\
									\
      static _GLIBCXX_CONSTEXPR unsigned TYPE				\
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0; }			\
									\
      static _GLIBCXX_USE_CONSTEXPR int min_exponent = 0;		\
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = 0;		\
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = 0; 		\
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 0;		\
									\
      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = false;		\
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = false;		\
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = false;	\
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm	\
       = denorm_absent; 						\
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false;	\
									\
      static _GLIBCXX_CONSTEXPR unsigned TYPE 				\
      infinity() _GLIBCXX_USE_NOEXCEPT 					\
      { return static_cast<unsigned TYPE>(0); }				\
									\
      static _GLIBCXX_CONSTEXPR unsigned TYPE				\
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT 				\
      { return static_cast<unsigned TYPE>(0); }				\
									\
      static _GLIBCXX_CONSTEXPR unsigned TYPE				\
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT				\
      { return static_cast<unsigned TYPE>(0); }				\
									\
      static _GLIBCXX_CONSTEXPR unsigned TYPE 				\
      denorm_min() _GLIBCXX_USE_NOEXCEPT				\
      { return static_cast<unsigned TYPE>(0); }				\
									\
      static _GLIBCXX_USE_CONSTEXPR bool is_iec559 = false;		\
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;		\
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = true;		\
									\
      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_integral_traps; \
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false;	\
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style	\
	= round_toward_zero;						\
    };

#if __cplusplus >= 201103L

#define __INT_N_201103(TYPE)						\
      static constexpr TYPE 						\
      lowest() noexcept { return min(); }				\
      static constexpr int max_digits10 = 0;

#define __INT_N_U201103(TYPE)						\
      static constexpr unsigned TYPE  					\
      lowest() noexcept { return min(); }				\
      static constexpr int max_digits10 = 0;

#else
#define __INT_N_201103(TYPE)
#define __INT_N_U201103(TYPE)
#endif

#if !defined(__STRICT_ANSI__)
#ifdef __GLIBCXX_TYPE_INT_N_0
  __INT_N(__GLIBCXX_TYPE_INT_N_0, __GLIBCXX_BITSIZE_INT_N_0,
	  __INT_N_201103 (__GLIBCXX_TYPE_INT_N_0),
	  __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_0))
#endif
#ifdef __GLIBCXX_TYPE_INT_N_1
  __INT_N (__GLIBCXX_TYPE_INT_N_1, __GLIBCXX_BITSIZE_INT_N_1,
	  __INT_N_201103 (__GLIBCXX_TYPE_INT_N_1),
	  __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_1))
#endif
#ifdef __GLIBCXX_TYPE_INT_N_2
  __INT_N (__GLIBCXX_TYPE_INT_N_2, __GLIBCXX_BITSIZE_INT_N_2,
	  __INT_N_201103 (__GLIBCXX_TYPE_INT_N_2),
	  __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_2))
#endif
#ifdef __GLIBCXX_TYPE_INT_N_3
  __INT_N (__GLIBCXX_TYPE_INT_N_3, __GLIBCXX_BITSIZE_INT_N_3,
	  __INT_N_201103 (__GLIBCXX_TYPE_INT_N_3),
	  __INT_N_U201103 (__GLIBCXX_TYPE_INT_N_3))
#endif

#elif defined __STRICT_ANSI__ && defined __SIZEOF_INT128__
  __INT_N(__int128, 128,
	  __INT_N_201103 (__int128),
	  __INT_N_U201103 (__int128))
#endif

#undef __INT_N
#undef __INT_N_201103
#undef __INT_N_U201103


  /// numeric_limits<float> specialization.
  template<>
    struct numeric_limits<float>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR float
      min() _GLIBCXX_USE_NOEXCEPT { return __FLT_MIN__; }

      static _GLIBCXX_CONSTEXPR float
      max() _GLIBCXX_USE_NOEXCEPT { return __FLT_MAX__; }

#if __cplusplus >= 201103L
      static constexpr float
      lowest() noexcept { return -__FLT_MAX__; }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __FLT_MANT_DIG__;
      static _GLIBCXX_USE_CONSTEXPR int digits10 = __FLT_DIG__;
#if __cplusplus >= 201103L
      static constexpr int max_digits10
	 = __glibcxx_max_digits10 (__FLT_MANT_DIG__);
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = false;
      static _GLIBCXX_USE_CONSTEXPR int radix = __FLT_RADIX__;

      static _GLIBCXX_CONSTEXPR float
      epsilon() _GLIBCXX_USE_NOEXCEPT { return __FLT_EPSILON__; }

      static _GLIBCXX_CONSTEXPR float
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0.5F; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = __FLT_MIN_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = __FLT_MIN_10_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = __FLT_MAX_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = __FLT_MAX_10_EXP__;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = __FLT_HAS_INFINITY__;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = __FLT_HAS_QUIET_NAN__;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = has_quiet_NaN;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
	= bool(__FLT_HAS_DENORM__) ? denorm_present : denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss
       = __glibcxx_float_has_denorm_loss;

      static _GLIBCXX_CONSTEXPR float
      infinity() _GLIBCXX_USE_NOEXCEPT { return __builtin_huge_valf(); }

      static _GLIBCXX_CONSTEXPR float
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return __builtin_nanf(""); }

      static _GLIBCXX_CONSTEXPR float
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return __builtin_nansf(""); }

      static _GLIBCXX_CONSTEXPR float
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return __FLT_DENORM_MIN__; }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559
	= has_infinity && has_quiet_NaN && has_denorm == denorm_present;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_float_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before
       = __glibcxx_float_tinyness_before;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_to_nearest;
    };

#undef __glibcxx_float_has_denorm_loss
#undef __glibcxx_float_traps
#undef __glibcxx_float_tinyness_before

  /// numeric_limits<double> specialization.
  template<>
    struct numeric_limits<double>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR double
      min() _GLIBCXX_USE_NOEXCEPT { return __DBL_MIN__; }

      static _GLIBCXX_CONSTEXPR double
      max() _GLIBCXX_USE_NOEXCEPT { return __DBL_MAX__; }

#if __cplusplus >= 201103L
      static constexpr double
      lowest() noexcept { return -__DBL_MAX__; }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __DBL_MANT_DIG__;
      static _GLIBCXX_USE_CONSTEXPR int digits10 = __DBL_DIG__;
#if __cplusplus >= 201103L
      static constexpr int max_digits10
	 = __glibcxx_max_digits10 (__DBL_MANT_DIG__);
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = false;
      static _GLIBCXX_USE_CONSTEXPR int radix = __FLT_RADIX__;

      static _GLIBCXX_CONSTEXPR double
      epsilon() _GLIBCXX_USE_NOEXCEPT { return __DBL_EPSILON__; }

      static _GLIBCXX_CONSTEXPR double
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0.5; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = __DBL_MIN_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = __DBL_MIN_10_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = __DBL_MAX_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = __DBL_MAX_10_EXP__;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = __DBL_HAS_INFINITY__;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = __DBL_HAS_QUIET_NAN__;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = has_quiet_NaN;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
	= bool(__DBL_HAS_DENORM__) ? denorm_present : denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss
        = __glibcxx_double_has_denorm_loss;

      static _GLIBCXX_CONSTEXPR double
      infinity() _GLIBCXX_USE_NOEXCEPT { return __builtin_huge_val(); }

      static _GLIBCXX_CONSTEXPR double
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return __builtin_nan(""); }

      static _GLIBCXX_CONSTEXPR double
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return __builtin_nans(""); }

      static _GLIBCXX_CONSTEXPR double
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return __DBL_DENORM_MIN__; }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559
	= has_infinity && has_quiet_NaN && has_denorm == denorm_present;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_double_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before
       = __glibcxx_double_tinyness_before;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style
       = round_to_nearest;
    };

#undef __glibcxx_double_has_denorm_loss
#undef __glibcxx_double_traps
#undef __glibcxx_double_tinyness_before

  /// numeric_limits<long double> specialization.
  template<>
    struct numeric_limits<long double>
    {
      static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true;

      static _GLIBCXX_CONSTEXPR long double
      min() _GLIBCXX_USE_NOEXCEPT { return __LDBL_MIN__; }

      static _GLIBCXX_CONSTEXPR long double
      max() _GLIBCXX_USE_NOEXCEPT { return __LDBL_MAX__; }

#if __cplusplus >= 201103L
      static constexpr long double
      lowest() noexcept { return -__LDBL_MAX__; }
#endif

      static _GLIBCXX_USE_CONSTEXPR int digits = __LDBL_MANT_DIG__;
      static _GLIBCXX_USE_CONSTEXPR int digits10 = __LDBL_DIG__;
#if __cplusplus >= 201103L
      static _GLIBCXX_USE_CONSTEXPR int max_digits10
	 = __glibcxx_max_digits10 (__LDBL_MANT_DIG__);
#endif
      static _GLIBCXX_USE_CONSTEXPR bool is_signed = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_integer = false;
      static _GLIBCXX_USE_CONSTEXPR bool is_exact = false;
      static _GLIBCXX_USE_CONSTEXPR int radix = __FLT_RADIX__;

      static _GLIBCXX_CONSTEXPR long double
      epsilon() _GLIBCXX_USE_NOEXCEPT { return __LDBL_EPSILON__; }

      static _GLIBCXX_CONSTEXPR long double
      round_error() _GLIBCXX_USE_NOEXCEPT { return 0.5L; }

      static _GLIBCXX_USE_CONSTEXPR int min_exponent = __LDBL_MIN_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = __LDBL_MIN_10_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent = __LDBL_MAX_EXP__;
      static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = __LDBL_MAX_10_EXP__;

      static _GLIBCXX_USE_CONSTEXPR bool has_infinity = __LDBL_HAS_INFINITY__;
      static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = __LDBL_HAS_QUIET_NAN__;
      static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = has_quiet_NaN;
      static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm
	= bool(__LDBL_HAS_DENORM__) ? denorm_present : denorm_absent;
      static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss
	= __glibcxx_long_double_has_denorm_loss;

      static _GLIBCXX_CONSTEXPR long double
      infinity() _GLIBCXX_USE_NOEXCEPT { return __builtin_huge_vall(); }

      static _GLIBCXX_CONSTEXPR long double
      quiet_NaN() _GLIBCXX_USE_NOEXCEPT { return __builtin_nanl(""); }

      static _GLIBCXX_CONSTEXPR long double
      signaling_NaN() _GLIBCXX_USE_NOEXCEPT { return __builtin_nansl(""); }

      static _GLIBCXX_CONSTEXPR long double
      denorm_min() _GLIBCXX_USE_NOEXCEPT { return __LDBL_DENORM_MIN__; }

      static _GLIBCXX_USE_CONSTEXPR bool is_iec559
	= has_infinity && has_quiet_NaN && has_denorm == denorm_present;
      static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true;
      static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false;

      static _GLIBCXX_USE_CONSTEXPR bool traps = __glibcxx_long_double_traps;
      static _GLIBCXX_USE_CONSTEXPR bool tinyness_before =
					 __glibcxx_long_double_tinyness_before;
      static _GLIBCXX_USE_CONSTEXPR float_round_style round_style =
						      round_to_nearest;
    };

#undef __glibcxx_long_double_has_denorm_loss
#undef __glibcxx_long_double_traps
#undef __glibcxx_long_double_tinyness_before

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace

#undef __glibcxx_signed
#undef __glibcxx_min
#undef __glibcxx_max
#undef __glibcxx_digits
#undef __glibcxx_digits10
#undef __glibcxx_max_digits10

#endif // _GLIBCXX_NUMERIC_LIMITS
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     (  0  (                                        (                 (                                    @               @                                           0               0                                                                                                                                                                                                                                                                          (                                                                               (    0  8  0  (                     8  0  (                     8                         (  0  (                   0                       (  8  (                 8                             (    0  8   8  0  (                                             (    0  8  p  8  0  (                     p  8  0  (                     p                         (    0  8    8  0  (                                              (    0  8    8  0  (                                                                      8               8                       (    (                                                                              (  0    0  (                                            (    0  8  P X P 8  0  (                     P                      (    (   (                                          (    0  8    8  0  (                                              (    0  8       8  0  (                                           (    (                                                                            (  ( (                 (                        (    0  8  ` h ` 8  0  (                     `                        (  0  @ 0  (                   @                        (    0  8       8  0  (                                             (    0  8  @ H @ 8  0  (                     @                        (    0  8     8  0  (                                             (    0  8       8  0  (                                             (    0  8  h p h 8  0  (                     h                      (   (                                         (    0  8  0 8 0 8  0  (                     0                        (    0  8  h 8  0  (                     h                        (    0  8  0  (                     8                                    `   h                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            m    __fentry__                                              9[    __x86_return_thunk                                      VS    this_cpu_off                                            d    _raw_spin_lock                                          4K    _raw_spin_unlock                                        ~    _printk                                                 H    register_netdevice_notifier                             \    rtnl_link_register                                       /m    genl_register_family                                    ƥy    rtnl_link_unregister                                    b
    unregister_netdevice_notifier                               nla_memcpy                                              V
    __stack_chk_fail                                        !N    free_percpu                                             z    kfree                                                   +!    crypto_destroy_tfm                                      E:#    __kmalloc                                               ۚ    crypto_alloc_aead                                       Z    crypto_aead_setkey                                      _f    crypto_aead_setauthsize                                 qH    nla_put_64bit                                           h    nla_put                                                     memmove                                                 !`    skb_pull                                                >    ___pskb_trim                                            ,[    ether_setup                                             *    dst_release                                                 dev_fetch_sw_netstats                                       dev_mc_sync                                             f    dev_uc_sync                                             o
    dev_set_allmulti                                        ~    dev_set_promiscuity                                     T    gro_cells_destroy                                            genl_unregister_family                                  >`    rcu_barrier                                             gj(    call_rcu                                                _i    refcount_warn_saturate                                  6    _raw_spin_lock_bh                                       !`    _raw_spin_unlock_bh                                     eb,    __dynamic_pr_debug                                      v    kfree_sensitive                                         L3)F    __preempt_count                                         "ޫ    __dev_queue_xmit                                        9?<    __local_bh_enable_ip                                    h6y    __alloc_percpu_gfp                                      }    nr_cpu_ids                                              u?h    __cpu_possible_mask                                     S    _find_next_bit                                          	    gro_cells_init                                          (
    dev_addr_mod                                            GV    __warn_printk                                           y6    eth_type_trans                                          ^a    gro_cells_receive                                       j    kfree_skb_reason                                            __dev_get_by_index                                          register_netdevice                                      M    netdev_upper_dev_link                                       netdev_upper_dev_unlink                                 +A%    unregister_netdevice_queue                              H    metadata_dst_alloc                                      h    __list_add_valid                                        a+a    netif_stacked_transfer_operstate                        M    linkwatch_fire_event                                    y    __x86_indirect_thunk_r13                                -    kmalloc_caches                                          wX    kmalloc_trace                                           =4    netdev_rx_handler_register                              82    mutex_unlock                                            KM    mutex_lock                                              [    skb_copy                                                #WK    consume_skb                                             ZA    skb_push                                                S>    skb_put                                                 ،D    skb_cow_data                                            !ʈ    sg_init_table                                           s    skb_to_sgvec                                                crypto_aead_encrypt                                     !    skb_copy_expand                                         'R    __rcu_read_lock                                         c*    skb_clone                                               plk    __netif_rx                                              i$    __rcu_read_unlock                                       76    crypto_aead_decrypt                                     pHe    __x86_indirect_thunk_rax                                k    __pskb_pull_tail                                        UrS    __list_del_entry_valid                                  oo#L    __x86_indirect_thunk_r15                                `i    netdev_rx_handler_unregister                            =[    dev_set_mtu                                             1ޟ    unregister_netdevice_many                                   netif_carrier_off                                       4    dev_mc_unsync                                           6    dev_uc_unsync                                           =G|    dev_uc_del                                              Dׯ    __x86_indirect_thunk_rbp                                b    dev_uc_add                                              ST    __per_cpu_offset                                        g    __x86_indirect_thunk_rbx                                #X    __nla_parse                                                 rtnl_lock                                               rn    rtnl_unlock                                             .^8U    __x86_indirect_thunk_r14                                I    netif_carrier_on                                        Bs    __alloc_percpu                                          8߬i    memcpy                                                  ŏW    memset                                                      fortify_panic                                           b    __x86_indirect_thunk_r12                                [!    genlmsg_put                                             e,    skb_trim                                                zR    module_layout                                                             
		         	        .          9		        ,		        	        	        	        	        	        	        	        	        	        	        	                                                                                                                                                                                                                                                                                                                         macsec             	                                                                                                                                                     macsec                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0         ,  ,             A=     T=    d=    u=    =    =    =    =    =    = 	   	> 
   >    (>    C> 
   Z>    j>    ~>    > 
     >     >    >    >    >    ?    ?    /?    F?    ]? 	   q? 
   ? 
   ? 	   ?      ?     ?    ?    ?    @    5@    N@    g@    @    @ 	   @ 
   @    @    @ 
   
A    A    6A    KA    `A 	     rA     A    A    A    A    A    A    B    (B    =B 
     MB     cB    uB    B    B    B    B    B    B    C 	   C 
   *C 
   =C 	   PC      eC     C    C    C    C    C    C      D     "D    6D    JD    ^D    rD    D    D    D    D 	   D 
   D      E     "E    ME    xE    E    E    E    F    5F    ^F 	   F 
   F    F    F    G    !G      6G     RG    rG    G    G    G    H    7H    _H    zH    H    H 	     H     H    I    5I    aI    I    I    I    I    I 
     J     0J    YJ    J    J    J    J    "K    HK    oK 	   K 
   K 
   K 	          
>e         
?e         
Ge         
He         
Ne         
Te         
`e  K      fN <      K $   p   K $   x    $   ~  L B      L *              #L )      ] 4e      ;L          k     ] C                L *      !_ 3e      FL          m     ] B   @   ML   @   0  Ae                    
o ]L      q` Te      ; %  @        0  r   hL `     x@	 n  @  | e           o nL      hL `                ` Pe      ` Je      ~L                 t @   ` $      v K      L K                 f	               
v        q        s        Ne         p        f        e        c        d        ]e         Fe         z        j        n        l        h        g        u L       L    p   L    k        
      :"  	  L           
Q   :"  	  L           
  :"  	  L           
   P %
    %
   s	  L           
       :"  %  P %
    %
   s	   M     M    I M    I       
    4M x ;M           
   :"  %  P %
    %
   s	  JM           
   :"  %    %
  \M     uM    j  M    j  M    'I M    I M    ZI M    j  M    j        
    :"  %  X+    M     N    j  %N    j        
  :"  %      5N     IN    j  [N    j  kN    s  }N    d        
   q` ]e  :"  %     eg  o	  N           
    :"  %  % [e  N           
    :"  %  % Ye  N           
    :"  %  ` Fe  % Ze  N           
    :"  %  ` Fe  N    ` Je  % De  N           
    :"  %  N    ` Pe  % Me  N     N    k  N    k  
O    k  O    k        
K     %
  -O     =O    k  MO    k  ]O    k  mO    k  }O    k  O    k        
Fe        %
  O %
  B  O  O    ǈ       
<e    ?   6C     _    O    Ɉ       
	   	  O    ˈ       
    D  fD      O    ͈       
       _ $   g  $   O    ψ       
K      q` ]e  ] *   	P    ш       
   <e     ,j F  P    'P    ӈ 8P    ͈       
    q` ]e  ` Pe  LP    ֈ       
  4M x   _e  ^P    ؈       
  | e  4M x   _e  mP    ڈ       
K   | e  4M x ~P    ܈       
3e    O-   i  A   P    ވ       
    gH  Pe  P     P    :.        
    gH  Je  P     P    :.        
    pU Fe  P     P    :.         
9                 o          
 IFLA_MACSEC_UNSPEC IFLA_MACSEC_SCI IFLA_MACSEC_PORT IFLA_MACSEC_ICV_LEN IFLA_MACSEC_CIPHER_SUITE IFLA_MACSEC_WINDOW IFLA_MACSEC_ENCODING_SA IFLA_MACSEC_ENCRYPT IFLA_MACSEC_PROTECT IFLA_MACSEC_INC_SCI IFLA_MACSEC_ES IFLA_MACSEC_SCB IFLA_MACSEC_REPLAY_PROTECT IFLA_MACSEC_VALIDATION IFLA_MACSEC_PAD IFLA_MACSEC_OFFLOAD __IFLA_MACSEC_MAX macsec_attrs MACSEC_ATTR_UNSPEC MACSEC_ATTR_IFINDEX MACSEC_ATTR_RXSC_CONFIG MACSEC_ATTR_SA_CONFIG MACSEC_ATTR_SECY MACSEC_ATTR_TXSA_LIST MACSEC_ATTR_RXSC_LIST MACSEC_ATTR_TXSC_STATS MACSEC_ATTR_SECY_STATS MACSEC_ATTR_OFFLOAD __MACSEC_ATTR_END NUM_MACSEC_ATTR MACSEC_ATTR_MAX macsec_secy_attrs MACSEC_SECY_ATTR_UNSPEC MACSEC_SECY_ATTR_SCI MACSEC_SECY_ATTR_ENCODING_SA MACSEC_SECY_ATTR_WINDOW MACSEC_SECY_ATTR_CIPHER_SUITE MACSEC_SECY_ATTR_ICV_LEN MACSEC_SECY_ATTR_PROTECT MACSEC_SECY_ATTR_REPLAY MACSEC_SECY_ATTR_OPER MACSEC_SECY_ATTR_VALIDATE MACSEC_SECY_ATTR_ENCRYPT MACSEC_SECY_ATTR_INC_SCI MACSEC_SECY_ATTR_ES MACSEC_SECY_ATTR_SCB MACSEC_SECY_ATTR_PAD __MACSEC_SECY_ATTR_END NUM_MACSEC_SECY_ATTR MACSEC_SECY_ATTR_MAX macsec_rxsc_attrs MACSEC_RXSC_ATTR_UNSPEC MACSEC_RXSC_ATTR_SCI MACSEC_RXSC_ATTR_ACTIVE MACSEC_RXSC_ATTR_SA_LIST MACSEC_RXSC_ATTR_STATS MACSEC_RXSC_ATTR_PAD __MACSEC_RXSC_ATTR_END NUM_MACSEC_RXSC_ATTR MACSEC_RXSC_ATTR_MAX macsec_sa_attrs MACSEC_SA_ATTR_UNSPEC MACSEC_SA_ATTR_AN MACSEC_SA_ATTR_ACTIVE MACSEC_SA_ATTR_PN MACSEC_SA_ATTR_KEY MACSEC_SA_ATTR_KEYID MACSEC_SA_ATTR_STATS MACSEC_SA_ATTR_PAD MACSEC_SA_ATTR_SSCI MACSEC_SA_ATTR_SALT __MACSEC_SA_ATTR_END NUM_MACSEC_SA_ATTR MACSEC_SA_ATTR_MAX macsec_offload_attrs MACSEC_OFFLOAD_ATTR_UNSPEC MACSEC_OFFLOAD_ATTR_TYPE MACSEC_OFFLOAD_ATTR_PAD __MACSEC_OFFLOAD_ATTR_END NUM_MACSEC_OFFLOAD_ATTR MACSEC_OFFLOAD_ATTR_MAX macsec_nl_commands MACSEC_CMD_GET_TXSC MACSEC_CMD_ADD_RXSC MACSEC_CMD_DEL_RXSC MACSEC_CMD_UPD_RXSC MACSEC_CMD_ADD_TXSA MACSEC_CMD_DEL_TXSA MACSEC_CMD_UPD_TXSA MACSEC_CMD_ADD_RXSA MACSEC_CMD_DEL_RXSA MACSEC_CMD_UPD_RXSA MACSEC_CMD_UPD_OFFLOAD macsec_rxsc_stats_attr MACSEC_RXSC_STATS_ATTR_UNSPEC MACSEC_RXSC_STATS_ATTR_IN_OCTETS_VALIDATED MACSEC_RXSC_STATS_ATTR_IN_OCTETS_DECRYPTED MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNCHECKED MACSEC_RXSC_STATS_ATTR_IN_PKTS_DELAYED MACSEC_RXSC_STATS_ATTR_IN_PKTS_OK MACSEC_RXSC_STATS_ATTR_IN_PKTS_INVALID MACSEC_RXSC_STATS_ATTR_IN_PKTS_LATE MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_VALID MACSEC_RXSC_STATS_ATTR_IN_PKTS_NOT_USING_SA MACSEC_RXSC_STATS_ATTR_IN_PKTS_UNUSED_SA MACSEC_RXSC_STATS_ATTR_PAD __MACSEC_RXSC_STATS_ATTR_END NUM_MACSEC_RXSC_STATS_ATTR MACSEC_RXSC_STATS_ATTR_MAX macsec_sa_stats_attr MACSEC_SA_STATS_ATTR_UNSPEC MACSEC_SA_STATS_ATTR_IN_PKTS_OK MACSEC_SA_STATS_ATTR_IN_PKTS_INVALID MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_VALID MACSEC_SA_STATS_ATTR_IN_PKTS_NOT_USING_SA MACSEC_SA_STATS_ATTR_IN_PKTS_UNUSED_SA MACSEC_SA_STATS_ATTR_OUT_PKTS_PROTECTED MACSEC_SA_STATS_ATTR_OUT_PKTS_ENCRYPTED __MACSEC_SA_STATS_ATTR_END NUM_MACSEC_SA_STATS_ATTR MACSEC_SA_STATS_ATTR_MAX macsec_txsc_stats_attr MACSEC_TXSC_STATS_ATTR_UNSPEC MACSEC_TXSC_STATS_ATTR_OUT_PKTS_PROTECTED MACSEC_TXSC_STATS_ATTR_OUT_PKTS_ENCRYPTED MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_PROTECTED MACSEC_TXSC_STATS_ATTR_OUT_OCTETS_ENCRYPTED MACSEC_TXSC_STATS_ATTR_PAD __MACSEC_TXSC_STATS_ATTR_END NUM_MACSEC_TXSC_STATS_ATTR MACSEC_TXSC_STATS_ATTR_MAX macsec_secy_stats_attr MACSEC_SECY_STATS_ATTR_UNSPEC MACSEC_SECY_STATS_ATTR_OUT_PKTS_UNTAGGED MACSEC_SECY_STATS_ATTR_IN_PKTS_UNTAGGED MACSEC_SECY_STATS_ATTR_OUT_PKTS_TOO_LONG MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_TAG MACSEC_SECY_STATS_ATTR_IN_PKTS_BAD_TAG MACSEC_SECY_STATS_ATTR_IN_PKTS_UNKNOWN_SCI MACSEC_SECY_STATS_ATTR_IN_PKTS_NO_SCI MACSEC_SECY_STATS_ATTR_IN_PKTS_OVERRUN MACSEC_SECY_STATS_ATTR_PAD __MACSEC_SECY_STATS_ATTR_END NUM_MACSEC_SECY_STATS_ATTR MACSEC_SECY_STATS_ATTR_MAX macsec_eth_header tci_an short_length packet_number secure_channel_id short_secure_channel_id gcm_iv_xpn gcm_iv pcpu_secy_stats macsec_dev secys macsec_rxh_data macsec_cb has_sci macsec_exit macsec_init macsec_notify macsec_fill_info macsec_get_size macsec_get_link_net macsec_validate_attr macsec_newlink macsec_dellink macsec_common_dellink macsec macsec_del_dev macsec_changelink macsec_changelink_common macsec_setup macsec_free_netdev macsec_get_iflink macsec_get_stats64 macsec_change_mtu macsec_set_mac_address macsec_dev_set_rx_mode macsec_dev_change_rx_flags macsec_dev_stop macsec_dev_open macsec_fix_features macsec_dev_uninit macsec_dev_init macsec_start_xmit macsec_dump_txsc dump_secy get_secy_stats get_tx_sc_stats get_rx_sc_stats an get_rx_sa_stats get_tx_sa_stats macsec_upd_offload macsec_upd_rxsc macsec_upd_rxsa macsec_upd_txsa validate_upd_sa macsec_del_txsa macsec_del_rxsc macsec_del_rxsa macsec_add_txsa macsec_add_rxsc macsec_add_rxsa tb_rxsc secyp get_rxsc_from_nl macsec_alloc_tfm macsec_handle_frame macsec_decrypt_done macsec_finalize_skb macsec_post_decrypt num_frags macsec_alloc_req macsec_encrypt_done macsec_pn_wrapped macsec_get_ops __macsec_get_ops macsec_check_offload make_sci macsec_txsa_put free_txsa macsec_rxsa_put free_rxsa macsec_rxsc_put free_rx_sc_rcu   macsec.ko   G*m                                                                                                   	                                                                                        $                      *                      ,                      -                      /                      3                      
                      m       	       0                   =     v              V            	       l                               <                                       $                                                                                     b           p             (    p      .       <          9       N                 `                  t                              h          $                   *                   -         h           0      w                            `                `                       )                 )                 a       )    P             :          7      O    
      L       X    `
            i                 }    
      k           `                
      I                  0           @      I                 )                 l            0      "                   )           `      >       .          a       E   /         8       ^    `      >       n                           >                                  =         ,                          ^                                  b           `      }          %      
      
   3                 #   $               5                G    `3      T      ]    4      ;       l     5      d      z    p6      Q          7      <          9      ;          P:      H                           <      f                 `           ?      ]          p@                 C            /    D      L      ?    0F            N    G      9      ^   	                s     K                L      7         	                    P      #          0R      Z          @      0           T               ,                  	 7       b           `Z      w      ,   ,               =   	        b       R    _            d    b            t    f            ~    y                                                                          /       '           V                 &                #   (                L                   _                 o                                           7                    L                    e                                                                                                                                                                     1                                                                              (                     3                     @                     Y                     l            )       {                                          L                                                                                                                                                                        	                     '	                     9	                     H	                     V	                     b	                     p	                     {	            h       	                     	                     	                     	                     	                     	                     +
                     	                     
                     )
                     @
                     T
                     d
                     w
                     
                     
                     
                     
                     
                     
                     
                                          ,                     =                     O                     Z                     c                     |                                                                                                                                                                                              .                     5                     H                     S                     ^                                          o                     |                                                     L                                                                                                                                     
                     
                     %
                     3
                     ~                     E
                     P
                     Y
                     c
                     v
                     
                     
                     
                     
                     
                     
                     
                                                                                    +                     9                     N                     _                     l                     z                                                                __crc_macsec_pn_wrapped __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 __kstrtab_macsec_pn_wrapped __kstrtabns_macsec_pn_wrapped __ksymtab_macsec_pn_wrapped macsec_check_offload macsec_post_decrypt macsec_fix_features macsec_change_mtu macsec_get_iflink macsec_get_link_net macsec_get_size macsec_init macsec_notifier macsec_link_ops macsec_fam __macsec_get_ops validate_upd_sa macsec_changelink_common free_rx_sc_rcu free_rxsa free_txsa macsec_alloc_req macsec_alloc_tfm macsec_validate_attr make_sci macsec_fill_info macsec_finalize_skb macsec_setup macsec_netdev_ops macsec_free_netdev macsec_type macsec_get_stats64 macsec_dev_set_rx_mode macsec_dev_change_rx_flags macsec_dev_uninit macsec_exit macsec_rxsa_put macsec_count_tx.isra.0 __UNIQUE_ID_ddebug661.12 macsec_txsa_put macsec_encrypt_done macsec_rxsc_put macsec_del_dev macsec_dev_init __already_done.4 macsec_decrypt_done get_rxsc_from_nl macsec_newlink macsec_handle_frame qdisc_tx_busylock_key.77 macsec_generation macsec_start_xmit macsec_common_dellink macsec_dellink macsec_notify macsec_dev_stop macsec_set_mac_address get_tx_sa_stats macsec_del_txsa macsec_genl_sa_policy macsec_del_rxsc macsec_genl_rxsc_policy get_rx_sa_stats macsec_del_rxsa macsec_dev_open get_tx_sc_stats get_secy_stats macsec_upd_txsa macsec_upd_txsa.cold get_rx_sc_stats macsec_upd_rxsa macsec_upd_rxsa.cold macsec_upd_rxsc macsec_upd_offload macsec_genl_offload_policy macsec_add_rxsa __already_done.9 macsec_add_rxsa.cold macsec_add_txsa __already_done.8 macsec_add_txsa.cold macsec_changelink macsec_add_rxsc dump_secy macsec_dump_txsc __func__.76 __UNIQUE_ID_license703 __UNIQUE_ID_description702 __UNIQUE_ID_alias701 __UNIQUE_ID_alias700 __UNIQUE_ID___addressable_cleanup_module699 __UNIQUE_ID___addressable_init_module698 macsec_rtnl_policy macsec_genl_ops macsec_genl_policy .LC2 .LC6 .LC7 .LC23 dev_set_mtu rtnl_unlock dev_mc_sync skb_put __x86_indirect_thunk_rbp __rcu_read_lock consume_skb __this_module memmove nla_put_64bit dev_uc_sync dev_uc_del this_cpu_off __x86_indirect_thunk_r15 rtnl_link_register cleanup_module genlmsg_put ___pskb_trim kfree dev_set_promiscuity crypto_alloc_aead gro_cells_init crypto_aead_setauthsize crypto_aead_decrypt unregister_netdevice_queue __per_cpu_offset gro_cells_destroy _raw_spin_lock dev_uc_unsync ether_setup fortify_panic __fentry__ init_module netdev_upper_dev_link dev_fetch_sw_netstats dev_addr_mod crypto_destroy_tfm eth_type_trans __x86_indirect_thunk_rax netdev_rx_handler_unregister __stack_chk_fail refcount_warn_saturate _raw_spin_unlock_bh skb_copy_expand __alloc_percpu_gfp crypto_aead_setkey __list_add_valid __dev_get_by_index rtnl_link_unregister skb_pull __rcu_read_unlock __x86_indirect_thunk_r14 crypto_aead_encrypt netif_stacked_transfer_operstate kfree_skb_reason gro_cells_receive mutex_lock skb_push __x86_indirect_thunk_rbx netdev_upper_dev_unlink nla_put kfree_sensitive __x86_indirect_thunk_r13 _find_next_bit __list_del_entry_valid __local_bh_enable_ip unregister_netdevice_many __cpu_possible_mask memset __x86_return_thunk nla_memcpy nr_cpu_ids __pskb_pull_tail skb_cow_data unregister_netdevice_notifier free_percpu __preempt_count call_rcu __dev_queue_xmit mutex_unlock linkwatch_fire_event dev_set_allmulti __alloc_percpu __dynamic_pr_debug __warn_printk netif_carrier_off __netif_rx skb_copy skb_clone metadata_dst_alloc _raw_spin_lock_bh dst_release netif_carrier_on rtnl_lock netdev_rx_handler_register dev_uc_add __x86_indirect_thunk_r12 genl_unregister_family kmalloc_trace rcu_barrier __nla_parse dev_mc_unsync genl_register_family _raw_spin_unlock skb_to_sgvec sg_init_table __kmalloc kmalloc_caches register_netdevice                              '             @             ^             q                                       |                                    )            .            q                                                                                                            !            +            1            m                                                            ,            Q            a            P                        N            a            n            x                                                                                                                                    =            Q            j                   p                                                                                                	            l	            	            
            
            S
            X
            a
            
                        -            T            {                                                            >            `                                                            
            +
            @
            i
            q
            
            
            
            `      
            
      
                   
            
                        
                        5            A            ]                                             |                                                   (            1            A            N            a            }                                                                                                                  '            C            J                    Q                    V            a            }                                                                                          ?            S            o                                                            `                                          s                                                                                                                                	                        Z         
   m            (       w            `       }         
                                                   Z                                                                                    !            N                                                                        a                        m            %      {                     
                                               (            X            {                                                                                                                                                                                                           u                                           $            %      3            G            y                                                            #                                                                     }                             1                                                          R!            h!            !            '"            1"            W"            x"            "             #            :#            T#            $            +$                    2$                    7$            $            $            $            $            %%            ;%            d%            %            %            %            N&            _&            &            &            &            	'            '            S'            f'            '            '            (            (            )            )            
*            *            *            i+            +            +                  +            +            ,            w,            ,            
-            $-            0-            -            -            '.            Q.            M/            /            /            /            ,0            0            0            H1            _1            1            1            2            2            2            2            3            :3            C3            a3            3            3            3            4                   34            y4            4            4            4            4            4            4            4            5            35            %      V5            5         z   5            F6            N6            V6            `6            q6            6            6            6            6            7            7            77            7            7            7            7            7            18            h8            8         ~   8            8            8            9            9            9            [9                    l9            v9                    {9            9            9            :            +:            @:            G:            Q:            :                  :            :            :            ;         {   ;            <            R<            e<            v<         {   <            <            =                   =            1=            E=            =            >         {   >>            >         ~   >         {   >            >            ?            ?            `?                    ?            ?                    ?            ?            ?            2@            M@            b@            i@            q@            @                  A            1A                   AA            SA            wA         {   A            B            B            B            B         {   C            !C            ZC            C            C            C            D            D            (D            vD            D            D            D            D            D            E            4E                    oE                    tE            zE            E            E            F            !F            (F            1F            mF            F                    F                    F             G            1G            G            G            G            G            G            H            
       H            
       'H                  7H            BH            
       RH            
       WH            {H            H            I            &I            8I            J            8J            EJ            bJ         {   J            J            J            J            K            ?K            XK                    K                    K            K            $L            }L            L            L            L            L            %M            (       2M            (       HM                   XM            aM            (       nM            (       M                  M            M            (       M            (       M            M         {   N            qN                   }N            N            N            TO         ~   O            O            O            O            O            P            yP                   P            P            2Q         {   aQ            Q            Q         {   Q         {   Q            R            R            1R            R            @      R            R            R            aS         {   S            T            eT            xT            T            T            U                  +U            UU                   eU            U            V            V            `V            3       V                   V            V            EW            bW            sW            W            W         {   X            I       CX            X                   X            X            Y            ;Y         {   EY         {   UY            kY            pY         {   Y            Y            Y         {   Y            Y         
   Z                  
Z            `       Z         
   Z            &Z         {   0Z            ?Z         {   NZ            g       SZ                   aZ            Z                  Z            6[            N[            v[            [            [                   \                   \            W\            \            \            \            3]            @]         {   U]                   ]                   ]            6^                   c^            ^            ^            ^         {   ^            ^            ^         {   _            &_            5_         {   P_            [_         
   q_                  x_            `       _         
   _            _         {   _            _         {   _                   _            b            ]b            b            b            b            b            'c                   7c            hc            xc            c            d         {   Md            Xd         {   nd                   }d            d            d            d                    d            d            ve            f         {   4f            Jf            ef            vf            f            5g                    Mg            g            g            g            &h            hh            h            h            %i            Oi            wi            i            i            i            j            >j            fj            j            j            j            $k            kk            k            k            l            ;l            l            l            l            m            Km            }m            m            m            "n            n            n             o            %o            yo            o            o            o            
p            {p            p            q            3q            Zq            q            q             r            Rr            r            r            r            s            Ls            ~s            s            $t            Tt            t            t            u            *u            Ou            u            u            u            v            2v            cw            w            w            w            %x            Hx            x            x            x            y            2y            8y                   y         {   y                         	                                                                    '          	           ,             9                     >             K          	           P             W                     \             d                                                         	                                                           %                                              
          {                bJ                          #             (          {   3             M      :                    ?             D          {   I             U      X                   ]             b          {   g             U      s             X      x             }          {                U                   ^                                 0                             {                [                   h                             {                [                                                {                [                   ^                                                                                                                       p                    p                                             (                    0                    8                     @             0      H                   P             `      X             `      `                   h                   p                   x             P                                      
                   `
                                      
                   
                   @                                                         0                   `                                                         `                                                                                                                                         (            `      0                  8            %      @            `3      H            4      P             5      X            p6      `            7      h            9      p            P:      x            <                  ?                  p@                   C                  D                  0F                  G                   K                  L                   P                  0R                  T                  `Z                  _                  b                  f                  y                                       ;                   n                   n                                                         !                   5"                    |"      $             &      (             &      ,             <(      0             V)      4             f.      8             /      <             0      @             1      D             (1                   {       `                  h            0      p             C      x            p6                                                                        7                                     @                  p                        (            y      8            b      P            <      h             P                  `Z                  P:                  G                  T                  p@                  L                  0R                    s                   ,                   w4                   7                   8                   :                   <                   >                    1@      $             B      (             tD      ,             E      0             ~G      4             J      8             |L      <             SO      @             Q      D             	T      H             X      L             ^      P             [b      T             te                                        &                    ?                    ]                                       (                                                                $                   (                   ,             *      0             l      4                   8                   <                   @                   D             <      H                   L                   P             	      T             R
      X                   \             ?
      `             h
      d             
      h             4      l                   p             '      t             |      x                   |                                |                                                         r                   ~                                                                                               W                   !                   &                   24                   4                   U5                   7                   g8                   9                   ;                   =>                   ?                   A                   C                   E                   0G                   J                   #L                   N                   `Q                   S                   
V                   5[                   b                  Ld                  h                  y                  c                                          b                    p                    w                    y                    // -*- C++ -*-

// Copyright (C) 2007-2022 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 parallel/algo.h
 *  @brief Parallel STL function calls corresponding to the stl_algo.h header.
 *
 *  The functions defined here mainly do case switches and
 *  call the actual parallelized versions in other files.
 *  Inlining policy: Functions that basically only contain one function call,
 *  are declared inline.
 *  This file is a GNU parallel extension to the Standard C++ Library.
 */

// Written by Johannes Singler and Felix Putze.

#ifndef _GLIBCXX_PARALLEL_ALGO_H
#define _GLIBCXX_PARALLEL_ALGO_H 1

#include <parallel/algorithmfwd.h>
#include <bits/stl_algobase.h>
#include <bits/stl_algo.h>
#include <parallel/iterator.h>
#include <parallel/base.h>
#include <parallel/sort.h>
#include <parallel/workstealing.h>
#include <parallel/par_loop.h>
#include <parallel/omp_loop.h>
#include <parallel/omp_loop_static.h>
#include <parallel/for_each_selectors.h>
#include <parallel/for_each.h>
#include <parallel/find.h>
#include <parallel/find_selectors.h>
#include <parallel/search.h>
#include <parallel/random_shuffle.h>
#include <parallel/partition.h>
#include <parallel/merge.h>
#include <parallel/unique_copy.h>
#include <parallel/set_operations.h>

namespace std _GLIBCXX_VISIBILITY(default)
{
namespace __parallel
{
  // Sequential fallback
  template<typename _IIter, typename _Function>
    inline _Function
    for_each(_IIter __begin, _IIter __end, _Function __f,
	     __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::for_each(__begin, __end, __f); }

  // Sequential fallback for input iterator case
  template<typename _IIter, typename _Function, typename _IteratorTag>
    inline _Function
    __for_each_switch(_IIter __begin, _IIter __end, _Function __f,
		      _IteratorTag)
    { return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators
  template<typename _RAIter, typename _Function>
    _Function
    __for_each_switch(_RAIter __begin, _RAIter __end,
		      _Function __f, random_access_iterator_tag,
		      __gnu_parallel::_Parallelism __parallelism_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().for_each_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  bool __dummy;
	  __gnu_parallel::__for_each_selector<_RAIter> __functionality;

	  return __gnu_parallel::
	    __for_each_template_random_access(
	      __begin, __end, __f, __functionality,
	      __gnu_parallel::_DummyReduct(), true, __dummy, -1,
	      __parallelism_tag);
	}
      else
	return for_each(__begin, __end, __f, __gnu_parallel::sequential_tag());
    }

  // Public interface
  template<typename _Iterator, typename _Function>
    inline _Function
    for_each(_Iterator __begin, _Iterator __end, _Function __f,
	     __gnu_parallel::_Parallelism __parallelism_tag)
    {
      return __for_each_switch(__begin, __end, __f,
			       std::__iterator_category(__begin),
			       __parallelism_tag);
    }

  template<typename _Iterator, typename _Function>
    inline _Function
    for_each(_Iterator __begin, _Iterator __end, _Function __f)
    {
      return __for_each_switch(__begin, __end, __f,
			       std::__iterator_category(__begin));
    }

  // Sequential fallback
  template<typename _IIter, typename _Tp>
    inline _IIter
    find(_IIter __begin, _IIter __end, const _Tp& __val,
	 __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::find(__begin, __end, __val); }

  // Sequential fallback for input iterator case
  template<typename _IIter, typename _Tp, typename _IteratorTag>
    inline _IIter
    __find_switch(_IIter __begin, _IIter __end, const _Tp& __val,
		_IteratorTag)
    { return _GLIBCXX_STD_A::find(__begin, __end, __val); }

  // Parallel find for random access iterators
  template<typename _RAIter, typename _Tp>
    _RAIter
    __find_switch(_RAIter __begin, _RAIter __end,
		const _Tp& __val, random_access_iterator_tag)
    {
      typedef iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;

      if (_GLIBCXX_PARALLEL_CONDITION(true))
	{
	  __gnu_parallel::__binder2nd<__gnu_parallel::_EqualTo<_ValueType,
							       const _Tp&>,
				      _ValueType, const _Tp&, bool>
	    __comp(__gnu_parallel::_EqualTo<_ValueType, const _Tp&>(), __val);
	  return __gnu_parallel::__find_template(
		   __begin, __end, __begin, __comp,
		   __gnu_parallel::__find_if_selector()).first;
	}
      else
	return _GLIBCXX_STD_A::find(__begin, __end, __val);
    }

  // Public interface
  template<typename _IIter, typename _Tp>
    inline _IIter
    find(_IIter __begin, _IIter __end, const _Tp& __val)
    {
      return __find_switch(__begin, __end, __val,
			   std::__iterator_category(__begin));
    }

  // Sequential fallback
  template<typename _IIter, typename _Predicate>
    inline _IIter
    find_if(_IIter __begin, _IIter __end, _Predicate __pred,
	    __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }

  // Sequential fallback for input iterator case
  template<typename _IIter, typename _Predicate, typename _IteratorTag>
    inline _IIter
    __find_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
		   _IteratorTag)
    { return _GLIBCXX_STD_A::find_if(__begin, __end, __pred); }

  // Parallel find_if for random access iterators
  template<typename _RAIter, typename _Predicate>
    _RAIter
    __find_if_switch(_RAIter __begin, _RAIter __end,
		   _Predicate __pred, random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(true))
	return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
					     __gnu_parallel::
					     __find_if_selector()).first;
      else
	return _GLIBCXX_STD_A::find_if(__begin, __end, __pred);
    }

  // Public interface
  template<typename _IIter, typename _Predicate>
    inline _IIter
    find_if(_IIter __begin, _IIter __end, _Predicate __pred)
    {
      return __find_if_switch(__begin, __end, __pred,
			      std::__iterator_category(__begin));
    }

  // Sequential fallback
  template<typename _IIter, typename _FIterator>
    inline _IIter
    find_first_of(_IIter __begin1, _IIter __end1,
		  _FIterator __begin2, _FIterator __end2,
		  __gnu_parallel::sequential_tag)
    {
      return _GLIBCXX_STD_A::find_first_of(__begin1, __end1, __begin2, __end2);
    }

  // Sequential fallback
  template<typename _IIter, typename _FIterator,
	   typename _BinaryPredicate>
    inline _IIter
    find_first_of(_IIter __begin1, _IIter __end1,
		  _FIterator __begin2, _FIterator __end2,
		  _BinaryPredicate __comp, __gnu_parallel::sequential_tag)
  { return _GLIBCXX_STD_A::find_first_of(
	     __begin1, __end1, __begin2, __end2, __comp); }

  // Sequential fallback for input iterator type
  template<typename _IIter, typename _FIterator,
	   typename _IteratorTag1, typename _IteratorTag2>
    inline _IIter
    __find_first_of_switch(_IIter __begin1, _IIter __end1,
			   _FIterator __begin2, _FIterator __end2,
			   _IteratorTag1, _IteratorTag2)
    { return find_first_of(__begin1, __end1, __begin2, __end2,
			   __gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators
  template<typename _RAIter, typename _FIterator,
	   typename _BinaryPredicate, typename _IteratorTag>
    inline _RAIter
    __find_first_of_switch(_RAIter __begin1,
			   _RAIter __end1,
			   _FIterator __begin2, _FIterator __end2,
			   _BinaryPredicate __comp, random_access_iterator_tag,
			   _IteratorTag)
    {
      return __gnu_parallel::
	__find_template(__begin1, __end1, __begin1, __comp,
		      __gnu_parallel::__find_first_of_selector
		      <_FIterator>(__begin2, __end2)).first;
    }

  // Sequential fallback for input iterator type
  template<typename _IIter, typename _FIterator,
	   typename _BinaryPredicate, typename _IteratorTag1,
	   typename _IteratorTag2>
    inline _IIter
    __find_first_of_switch(_IIter __begin1, _IIter __end1,
			   _FIterator __begin2, _FIterator __end2,
			   _BinaryPredicate __comp, _IteratorTag1, _IteratorTag2)
    { return find_first_of(__begin1, __end1, __begin2, __end2, __comp,
			   __gnu_parallel::sequential_tag()); }

  // Public interface
  template<typename _IIter, typename _FIterator,
	   typename _BinaryPredicate>
    inline _IIter
    find_first_of(_IIter __begin1, _IIter __end1,
		  _FIterator __begin2, _FIterator __end2,
		  _BinaryPredicate __comp)
    {
      return __find_first_of_switch(__begin1, __end1, __begin2, __end2, __comp,
				    std::__iterator_category(__begin1),
				    std::__iterator_category(__begin2));
    }

  // Public interface, insert default comparator
  template<typename _IIter, typename _FIterator>
    inline _IIter
    find_first_of(_IIter __begin1, _IIter __end1,
		  _FIterator __begin2, _FIterator __end2)
    {
      typedef typename std::iterator_traits<_IIter>::value_type _IValueType;
      typedef typename std::iterator_traits<_FIterator>::value_type _FValueType;

      return __gnu_parallel::find_first_of(__begin1, __end1, __begin2, __end2,
			 __gnu_parallel::_EqualTo<_IValueType, _FValueType>());
    }

  // Sequential fallback
  template<typename _IIter, typename _OutputIterator>
    inline _OutputIterator
    unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
		__gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out); }

  // Sequential fallback
  template<typename _IIter, typename _OutputIterator,
	   typename _Predicate>
    inline _OutputIterator
    unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
		_Predicate __pred, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::unique_copy(__begin1, __end1, __out, __pred); }

  // Sequential fallback for input iterator case
  template<typename _IIter, typename _OutputIterator,
	   typename _Predicate, typename _IteratorTag1, typename _IteratorTag2>
    inline _OutputIterator
    __unique_copy_switch(_IIter __begin, _IIter __last,
		       _OutputIterator __out, _Predicate __pred,
		       _IteratorTag1, _IteratorTag2)
    { return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred); }

  // Parallel unique_copy for random access iterators
  template<typename _RAIter, typename _RandomAccessOutputIterator,
	   typename _Predicate>
    _RandomAccessOutputIterator
    __unique_copy_switch(_RAIter __begin, _RAIter __last,
			 _RandomAccessOutputIterator __out, _Predicate __pred,
			 random_access_iterator_tag, random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__last - __begin)
	    > __gnu_parallel::_Settings::get().unique_copy_minimal_n))
	return __gnu_parallel::__parallel_unique_copy(
		 __begin, __last, __out, __pred);
      else
	return _GLIBCXX_STD_A::unique_copy(__begin, __last, __out, __pred);
    }

  // Public interface
  template<typename _IIter, typename _OutputIterator>
    inline _OutputIterator
    unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out)
    {
      typedef typename std::iterator_traits<_IIter>::value_type _ValueType;

      return __unique_copy_switch(
	       __begin1, __end1, __out, equal_to<_ValueType>(),
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__out));
    }

  // Public interface
  template<typename _IIter, typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    unique_copy(_IIter __begin1, _IIter __end1, _OutputIterator __out,
		_Predicate __pred)
    {
      return __unique_copy_switch(
	       __begin1, __end1, __out, __pred,
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__out));
    }

  // Sequential fallback
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    set_union(_IIter1 __begin1, _IIter1 __end1,
	      _IIter2 __begin2, _IIter2 __end2,
	      _OutputIterator __out, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::set_union(
	       __begin1, __end1, __begin2, __end2, __out); }

  // Sequential fallback
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    set_union(_IIter1 __begin1, _IIter1 __end1,
	      _IIter2 __begin2, _IIter2 __end2,
	      _OutputIterator __out, _Predicate __pred,
	      __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::set_union(__begin1, __end1,
				       __begin2, __end2, __out, __pred); }

  // Sequential fallback for input iterator case
  template<typename _IIter1, typename _IIter2, typename _Predicate,
	   typename _OutputIterator, typename _IteratorTag1,
	   typename _IteratorTag2, typename _IteratorTag3>
    inline _OutputIterator
    __set_union_switch(
      _IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
      _OutputIterator __result, _Predicate __pred,
      _IteratorTag1, _IteratorTag2, _IteratorTag3)
    { return _GLIBCXX_STD_A::set_union(__begin1, __end1,
				       __begin2, __end2, __result, __pred); }

  // Parallel set_union for random access iterators
  template<typename _RAIter1, typename _RAIter2,
	   typename _Output_RAIter, typename _Predicate>
    _Output_RAIter
    __set_union_switch(_RAIter1 __begin1, _RAIter1 __end1,
		       _RAIter2 __begin2, _RAIter2 __end2,
		       _Output_RAIter __result, _Predicate __pred,
		       random_access_iterator_tag, random_access_iterator_tag,
		       random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
	    >= __gnu_parallel::_Settings::get().set_union_minimal_n
	    || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
	    >= __gnu_parallel::_Settings::get().set_union_minimal_n))
	return __gnu_parallel::__parallel_set_union(
		 __begin1, __end1, __begin2, __end2, __result, __pred);
      else
	return _GLIBCXX_STD_A::set_union(__begin1, __end1,
					 __begin2, __end2, __result, __pred);
    }

  // Public interface
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    set_union(_IIter1 __begin1, _IIter1 __end1,
	      _IIter2 __begin2, _IIter2 __end2, _OutputIterator __out)
    {
      typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
      typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;

      return __set_union_switch(
	       __begin1, __end1, __begin2, __end2, __out,
	       __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__out));
    }

  // Public interface
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    set_union(_IIter1 __begin1, _IIter1 __end1,
	      _IIter2 __begin2, _IIter2 __end2,
	      _OutputIterator __out, _Predicate __pred)
    {
      return __set_union_switch(
	       __begin1, __end1, __begin2, __end2, __out, __pred,
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__out));
    }

  // Sequential fallback.
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    set_intersection(_IIter1 __begin1, _IIter1 __end1,
		     _IIter2 __begin2, _IIter2 __end2,
		     _OutputIterator __out, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1,
					      __begin2, __end2, __out); }

  // Sequential fallback.
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    set_intersection(_IIter1 __begin1, _IIter1 __end1,
		     _IIter2 __begin2, _IIter2 __end2,
		     _OutputIterator __out, _Predicate __pred,
		     __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::set_intersection(
	       __begin1, __end1, __begin2, __end2, __out, __pred); }

  // Sequential fallback for input iterator case
  template<typename _IIter1, typename _IIter2,
	   typename _Predicate, typename _OutputIterator,
	   typename _IteratorTag1, typename _IteratorTag2,
	   typename _IteratorTag3>
    inline _OutputIterator
    __set_intersection_switch(_IIter1 __begin1, _IIter1 __end1,
			      _IIter2 __begin2, _IIter2 __end2,
			      _OutputIterator __result, _Predicate __pred,
			      _IteratorTag1, _IteratorTag2, _IteratorTag3)
    { return _GLIBCXX_STD_A::set_intersection(__begin1, __end1, __begin2,
					      __end2, __result, __pred); }

  // Parallel set_intersection for random access iterators
  template<typename _RAIter1, typename _RAIter2,
	   typename _Output_RAIter, typename _Predicate>
    _Output_RAIter
    __set_intersection_switch(_RAIter1 __begin1,
			      _RAIter1 __end1,
			      _RAIter2 __begin2,
			      _RAIter2 __end2,
			      _Output_RAIter __result,
			      _Predicate __pred,
			      random_access_iterator_tag,
			      random_access_iterator_tag,
			      random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
	    >= __gnu_parallel::_Settings::get().set_union_minimal_n
	    || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
	    >= __gnu_parallel::_Settings::get().set_union_minimal_n))
	return __gnu_parallel::__parallel_set_intersection(
		 __begin1, __end1, __begin2, __end2, __result, __pred);
      else
	return _GLIBCXX_STD_A::set_intersection(
		 __begin1, __end1, __begin2, __end2, __result, __pred);
    }

  // Public interface
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    set_intersection(_IIter1 __begin1, _IIter1 __end1,
		     _IIter2 __begin2, _IIter2 __end2,
		     _OutputIterator __out)
    {
      typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
      typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;

      return __set_intersection_switch(
	       __begin1, __end1, __begin2, __end2, __out,
	       __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__out));
    }

  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    set_intersection(_IIter1 __begin1, _IIter1 __end1,
		     _IIter2 __begin2, _IIter2 __end2,
		     _OutputIterator __out, _Predicate __pred)
    {
      return __set_intersection_switch(
	       __begin1, __end1, __begin2, __end2, __out, __pred,
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__out));
    }

  // Sequential fallback
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
			     _IIter2 __begin2, _IIter2 __end2,
			     _OutputIterator __out,
			     __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::set_symmetric_difference(
	       __begin1, __end1, __begin2, __end2, __out); }

  // Sequential fallback
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
			     _IIter2 __begin2, _IIter2 __end2,
			     _OutputIterator __out, _Predicate __pred,
			     __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::set_symmetric_difference(
	       __begin1, __end1, __begin2, __end2, __out, __pred); }

  // Sequential fallback for input iterator case
  template<typename _IIter1, typename _IIter2,
	   typename _Predicate, typename _OutputIterator,
	   typename _IteratorTag1, typename _IteratorTag2,
	   typename _IteratorTag3>
    inline _OutputIterator
    __set_symmetric_difference_switch(
	_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2, _IIter2 __end2,
	_OutputIterator __result, _Predicate __pred,
	_IteratorTag1, _IteratorTag2, _IteratorTag3)
    { return _GLIBCXX_STD_A::set_symmetric_difference(
	       __begin1, __end1, __begin2, __end2, __result, __pred); }

  // Parallel set_symmetric_difference for random access iterators
  template<typename _RAIter1, typename _RAIter2,
	   typename _Output_RAIter, typename _Predicate>
    _Output_RAIter
    __set_symmetric_difference_switch(_RAIter1 __begin1,
				      _RAIter1 __end1,
				      _RAIter2 __begin2,
				      _RAIter2 __end2,
				      _Output_RAIter __result,
				      _Predicate __pred,
				      random_access_iterator_tag,
				      random_access_iterator_tag,
				      random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
      static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
      >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n
      || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
      >= __gnu_parallel::_Settings::get().set_symmetric_difference_minimal_n))
  return __gnu_parallel::__parallel_set_symmetric_difference(
	   __begin1, __end1, __begin2, __end2, __result, __pred);
      else
	return _GLIBCXX_STD_A::set_symmetric_difference(
		 __begin1, __end1, __begin2, __end2, __result, __pred);
    }

  // Public interface.
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
			     _IIter2 __begin2, _IIter2 __end2,
			     _OutputIterator __out)
    {
      typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
      typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;

      return __set_symmetric_difference_switch(
	       __begin1, __end1, __begin2, __end2, __out,
	       __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__out));
    }

  // Public interface.
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    set_symmetric_difference(_IIter1 __begin1, _IIter1 __end1,
			     _IIter2 __begin2, _IIter2 __end2,
			     _OutputIterator __out, _Predicate __pred)
    {
      return __set_symmetric_difference_switch(
	       __begin1, __end1, __begin2, __end2, __out, __pred,
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__out));
    }

  // Sequential fallback.
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    set_difference(_IIter1 __begin1, _IIter1 __end1,
		   _IIter2 __begin2, _IIter2 __end2,
		   _OutputIterator __out, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::set_difference(
	       __begin1,__end1, __begin2, __end2, __out); }

  // Sequential fallback.
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    set_difference(_IIter1 __begin1, _IIter1 __end1,
		   _IIter2 __begin2, _IIter2 __end2,
		   _OutputIterator __out, _Predicate __pred,
		   __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::set_difference(__begin1, __end1,
					    __begin2, __end2, __out, __pred); }

  // Sequential fallback for input iterator case.
  template<typename _IIter1, typename _IIter2, typename _Predicate,
	   typename _OutputIterator, typename _IteratorTag1,
	   typename _IteratorTag2, typename _IteratorTag3>
    inline _OutputIterator
    __set_difference_switch(_IIter1 __begin1, _IIter1 __end1,
			    _IIter2 __begin2, _IIter2 __end2,
			    _OutputIterator __result, _Predicate __pred,
			    _IteratorTag1, _IteratorTag2, _IteratorTag3)
    { return _GLIBCXX_STD_A::set_difference(
	       __begin1, __end1, __begin2, __end2, __result, __pred); }

  // Parallel set_difference for random access iterators
  template<typename _RAIter1, typename _RAIter2,
	   typename _Output_RAIter, typename _Predicate>
    _Output_RAIter
    __set_difference_switch(_RAIter1 __begin1,
			    _RAIter1 __end1,
			    _RAIter2 __begin2,
			    _RAIter2 __end2,
			    _Output_RAIter __result, _Predicate __pred,
			    random_access_iterator_tag,
			    random_access_iterator_tag,
			    random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
	    >= __gnu_parallel::_Settings::get().set_difference_minimal_n
	    || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
	    >= __gnu_parallel::_Settings::get().set_difference_minimal_n))
	return __gnu_parallel::__parallel_set_difference(
		 __begin1, __end1, __begin2, __end2, __result, __pred);
      else
	return _GLIBCXX_STD_A::set_difference(
		 __begin1, __end1, __begin2, __end2, __result, __pred);
    }

  // Public interface
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    set_difference(_IIter1 __begin1, _IIter1 __end1,
		   _IIter2 __begin2, _IIter2 __end2,
		   _OutputIterator __out)
    {
      typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
      typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;

      return __set_difference_switch(
	       __begin1, __end1, __begin2, __end2, __out,
	       __gnu_parallel::_Less<_ValueType1, _ValueType2>(),
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__out));
    }

  // Public interface
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Predicate>
    inline _OutputIterator
    set_difference(_IIter1 __begin1, _IIter1 __end1,
		   _IIter2 __begin2, _IIter2 __end2,
		   _OutputIterator __out, _Predicate __pred)
    {
      return __set_difference_switch(
	       __begin1, __end1, __begin2, __end2, __out, __pred,
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__out));
    }

  // Sequential fallback
  template<typename _FIterator>
    inline _FIterator
    adjacent_find(_FIterator __begin, _FIterator __end,
		  __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::adjacent_find(__begin, __end); }

  // Sequential fallback
  template<typename _FIterator, typename _BinaryPredicate>
    inline _FIterator
    adjacent_find(_FIterator __begin, _FIterator __end,
		  _BinaryPredicate __binary_pred,
		  __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::adjacent_find(__begin, __end, __binary_pred); }

  // Parallel algorithm for random access iterators
  template<typename _RAIter>
    _RAIter
    __adjacent_find_switch(_RAIter __begin, _RAIter __end,
			   random_access_iterator_tag)
    {
      typedef iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;

      if (_GLIBCXX_PARALLEL_CONDITION(true))
	{
	  _RAIter __spot = __gnu_parallel::
	      __find_template(
		__begin, __end - 1, __begin, equal_to<_ValueType>(),
		__gnu_parallel::__adjacent_find_selector())
	    .first;
	  if (__spot == (__end - 1))
	    return __end;
	  else
	    return __spot;
	}
      else
	return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag());
    }

  // Sequential fallback for input iterator case
  template<typename _FIterator, typename _IteratorTag>
    inline _FIterator
    __adjacent_find_switch(_FIterator __begin, _FIterator __end,
			   _IteratorTag)
    { return adjacent_find(__begin, __end, __gnu_parallel::sequential_tag()); }

  // Public interface
  template<typename _FIterator>
    inline _FIterator
    adjacent_find(_FIterator __begin, _FIterator __end)
    {
      return __adjacent_find_switch(__begin, __end,
				    std::__iterator_category(__begin));
    }

  // Sequential fallback for input iterator case
  template<typename _FIterator, typename _BinaryPredicate,
	   typename _IteratorTag>
    inline _FIterator
    __adjacent_find_switch(_FIterator __begin, _FIterator __end,
			   _BinaryPredicate __pred, _IteratorTag)
    { return adjacent_find(__begin, __end, __pred,
			   __gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators
  template<typename _RAIter, typename _BinaryPredicate>
    _RAIter
    __adjacent_find_switch(_RAIter __begin, _RAIter __end,
			   _BinaryPredicate __pred, random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(true))
	return __gnu_parallel::__find_template(__begin, __end, __begin, __pred,
					     __gnu_parallel::
					     __adjacent_find_selector()).first;
      else
	return adjacent_find(__begin, __end, __pred,
			     __gnu_parallel::sequential_tag());
    }

  // Public interface
  template<typename _FIterator, typename _BinaryPredicate>
    inline _FIterator
    adjacent_find(_FIterator __begin, _FIterator __end,
		  _BinaryPredicate __pred)
    {
      return __adjacent_find_switch(__begin, __end, __pred,
				    std::__iterator_category(__begin));
    }

  // Sequential fallback
  template<typename _IIter, typename _Tp>
    inline typename iterator_traits<_IIter>::difference_type
    count(_IIter __begin, _IIter __end, const _Tp& __value,
	  __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::count(__begin, __end, __value); }

  // Parallel code for random access iterators
  template<typename _RAIter, typename _Tp>
    typename iterator_traits<_RAIter>::difference_type
    __count_switch(_RAIter __begin, _RAIter __end,
		   const _Tp& __value, random_access_iterator_tag,
		   __gnu_parallel::_Parallelism __parallelism_tag)
    {
      typedef iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;
      typedef typename _TraitsType::difference_type _DifferenceType;
      typedef __gnu_parallel::_SequenceIndex _SequenceIndex;

      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().count_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  __gnu_parallel::__count_selector<_RAIter, _DifferenceType>
	    __functionality;
	  _DifferenceType __res = 0;
	  __gnu_parallel::
	    __for_each_template_random_access(
	      __begin, __end, __value, __functionality,
	      std::plus<_SequenceIndex>(), __res, __res, -1,
	      __parallelism_tag);
	  return __res;
	}
      else
	return count(__begin, __end, __value,
		     __gnu_parallel::sequential_tag());
    }

  // Sequential fallback for input iterator case.
  template<typename _IIter, typename _Tp, typename _IteratorTag>
    inline typename iterator_traits<_IIter>::difference_type
    __count_switch(_IIter __begin, _IIter __end, const _Tp& __value,
		   _IteratorTag)
    { return count(__begin, __end, __value, __gnu_parallel::sequential_tag());
      }

  // Public interface.
  template<typename _IIter, typename _Tp>
    inline typename iterator_traits<_IIter>::difference_type
    count(_IIter __begin, _IIter __end, const _Tp& __value,
	  __gnu_parallel::_Parallelism __parallelism_tag)
    {
      return __count_switch(__begin, __end, __value,
			    std::__iterator_category(__begin),
			    __parallelism_tag);
    }

  template<typename _IIter, typename _Tp>
    inline typename iterator_traits<_IIter>::difference_type
    count(_IIter __begin, _IIter __end, const _Tp& __value)
    {
      return __count_switch(__begin, __end, __value,
			    std::__iterator_category(__begin));
    }


  // Sequential fallback.
  template<typename _IIter, typename _Predicate>
    inline typename iterator_traits<_IIter>::difference_type
    count_if(_IIter __begin, _IIter __end, _Predicate __pred,
	     __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::count_if(__begin, __end, __pred); }

  // Parallel count_if for random access iterators
  template<typename _RAIter, typename _Predicate>
    typename iterator_traits<_RAIter>::difference_type
    __count_if_switch(_RAIter __begin, _RAIter __end,
		      _Predicate __pred, random_access_iterator_tag,
		      __gnu_parallel::_Parallelism __parallelism_tag)
    {
      typedef iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;
      typedef typename _TraitsType::difference_type _DifferenceType;
      typedef __gnu_parallel::_SequenceIndex _SequenceIndex;

      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().count_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  _DifferenceType __res = 0;
	  __gnu_parallel::
	    __count_if_selector<_RAIter, _DifferenceType>
	    __functionality;
	  __gnu_parallel::
	    __for_each_template_random_access(
	      __begin, __end, __pred, __functionality,
	      std::plus<_SequenceIndex>(), __res, __res, -1,
	      __parallelism_tag);
	  return __res;
	}
      else
	return count_if(__begin, __end, __pred,
			__gnu_parallel::sequential_tag());
    }

  // Sequential fallback for input iterator case.
  template<typename _IIter, typename _Predicate, typename _IteratorTag>
    inline typename iterator_traits<_IIter>::difference_type
    __count_if_switch(_IIter __begin, _IIter __end, _Predicate __pred,
		      _IteratorTag)
    { return count_if(__begin, __end, __pred,
		      __gnu_parallel::sequential_tag()); }

  // Public interface.
  template<typename _IIter, typename _Predicate>
    inline typename iterator_traits<_IIter>::difference_type
    count_if(_IIter __begin, _IIter __end, _Predicate __pred,
	     __gnu_parallel::_Parallelism __parallelism_tag)
    {
      return __count_if_switch(__begin, __end, __pred,
			       std::__iterator_category(__begin),
			       __parallelism_tag);
    }

  template<typename _IIter, typename _Predicate>
    inline typename iterator_traits<_IIter>::difference_type
    count_if(_IIter __begin, _IIter __end, _Predicate __pred)
    {
      return __count_if_switch(__begin, __end, __pred,
			       std::__iterator_category(__begin));
    }


  // Sequential fallback.
  template<typename _FIterator1, typename _FIterator2>
    inline _FIterator1
    search(_FIterator1 __begin1, _FIterator1 __end1,
	   _FIterator2 __begin2, _FIterator2 __end2,
	   __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::search(__begin1, __end1, __begin2, __end2); }

  // Parallel algorithm for random access iterator
  template<typename _RAIter1, typename _RAIter2>
    _RAIter1
    __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
		    _RAIter2 __begin2, _RAIter2 __end2,
		    random_access_iterator_tag, random_access_iterator_tag)
    {
      typedef typename std::iterator_traits<_RAIter1>::value_type _ValueType1;
      typedef typename std::iterator_traits<_RAIter2>::value_type _ValueType2;

      if (_GLIBCXX_PARALLEL_CONDITION(
		static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
	    >= __gnu_parallel::_Settings::get().search_minimal_n))
	return __gnu_parallel::
	  __search_template(
	    __begin1, __end1, __begin2, __end2,
	    __gnu_parallel::_EqualTo<_ValueType1, _ValueType2>());
      else
	return search(__begin1, __end1, __begin2, __end2,
		      __gnu_parallel::sequential_tag());
    }

  // Sequential fallback for input iterator case
  template<typename _FIterator1, typename _FIterator2,
	   typename _IteratorTag1, typename _IteratorTag2>
    inline _FIterator1
    __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
		    _FIterator2 __begin2, _FIterator2 __end2,
		    _IteratorTag1, _IteratorTag2)
    { return search(__begin1, __end1, __begin2, __end2,
		    __gnu_parallel::sequential_tag()); }

  // Public interface.
  template<typename _FIterator1, typename _FIterator2>
    inline _FIterator1
    search(_FIterator1 __begin1, _FIterator1 __end1,
	   _FIterator2 __begin2, _FIterator2 __end2)
    {
      return __search_switch(__begin1, __end1, __begin2, __end2,
			     std::__iterator_category(__begin1),
			     std::__iterator_category(__begin2));
    }

  // Public interface.
  template<typename _FIterator1, typename _FIterator2,
	   typename _BinaryPredicate>
    inline _FIterator1
    search(_FIterator1 __begin1, _FIterator1 __end1,
	   _FIterator2 __begin2, _FIterator2 __end2,
	   _BinaryPredicate __pred, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::search(
			       __begin1, __end1, __begin2, __end2, __pred); }

  // Parallel algorithm for random access iterator.
  template<typename _RAIter1, typename _RAIter2,
	   typename _BinaryPredicate>
    _RAIter1
    __search_switch(_RAIter1 __begin1, _RAIter1 __end1,
		    _RAIter2 __begin2, _RAIter2 __end2,
		    _BinaryPredicate __pred,
		    random_access_iterator_tag, random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
		static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
	    >= __gnu_parallel::_Settings::get().search_minimal_n))
	return __gnu_parallel::__search_template(__begin1, __end1,
					       __begin2, __end2, __pred);
      else
	return search(__begin1, __end1, __begin2, __end2, __pred,
		      __gnu_parallel::sequential_tag());
    }

  // Sequential fallback for input iterator case
  template<typename _FIterator1, typename _FIterator2,
	   typename _BinaryPredicate, typename _IteratorTag1,
	   typename _IteratorTag2>
    inline _FIterator1
    __search_switch(_FIterator1 __begin1, _FIterator1 __end1,
		    _FIterator2 __begin2, _FIterator2 __end2,
		    _BinaryPredicate __pred, _IteratorTag1, _IteratorTag2)
    { return search(__begin1, __end1, __begin2, __end2, __pred,
		    __gnu_parallel::sequential_tag()); }

  // Public interface
  template<typename _FIterator1, typename _FIterator2,
	   typename _BinaryPredicate>
    inline _FIterator1
    search(_FIterator1 __begin1, _FIterator1 __end1,
	   _FIterator2 __begin2, _FIterator2 __end2,
	   _BinaryPredicate  __pred)
    {
      return __search_switch(__begin1, __end1, __begin2, __end2, __pred,
			     std::__iterator_category(__begin1),
			     std::__iterator_category(__begin2));
    }

#if __cplusplus >= 201703L
  /** @brief Search a sequence using a Searcher object.
   *
   *  @param  __first        A forward iterator.
   *  @param  __last         A forward iterator.
   *  @param  __searcher     A callable object.
   *  @return @p __searcher(__first,__last).first
  */
  template<typename _ForwardIterator, typename _Searcher>
    inline _ForwardIterator
    search(_ForwardIterator __first, _ForwardIterator __last,
	   const _Searcher& __searcher)
    { return __searcher(__first, __last).first; }
#endif

  // Sequential fallback
  template<typename _FIterator, typename _Integer, typename _Tp>
    inline _FIterator
    search_n(_FIterator __begin, _FIterator __end, _Integer __count,
	     const _Tp& __val, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val); }

  // Sequential fallback
  template<typename _FIterator, typename _Integer, typename _Tp,
	   typename _BinaryPredicate>
    inline _FIterator
    search_n(_FIterator __begin, _FIterator __end, _Integer __count,
	     const _Tp& __val, _BinaryPredicate __binary_pred,
	     __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::search_n(
	       __begin, __end, __count, __val, __binary_pred); }

  // Public interface.
  template<typename _FIterator, typename _Integer, typename _Tp>
    inline _FIterator
    search_n(_FIterator __begin, _FIterator __end, _Integer __count,
	     const _Tp& __val)
    {
      typedef typename iterator_traits<_FIterator>::value_type _ValueType;
      return __gnu_parallel::search_n(__begin, __end, __count, __val,
		      __gnu_parallel::_EqualTo<_ValueType, _Tp>());
    }

  // Parallel algorithm for random access iterators.
  template<typename _RAIter, typename _Integer,
	   typename _Tp, typename _BinaryPredicate>
    _RAIter
    __search_n_switch(_RAIter __begin, _RAIter __end, _Integer __count,
		      const _Tp& __val, _BinaryPredicate __binary_pred,
		      random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
		static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().search_minimal_n))
	{
	  __gnu_parallel::_PseudoSequence<_Tp, _Integer> __ps(__val, __count);
	  return __gnu_parallel::__search_template(
		   __begin, __end, __ps.begin(), __ps.end(), __binary_pred);
	}
      else
	return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
					__binary_pred);
    }

  // Sequential fallback for input iterator case.
  template<typename _FIterator, typename _Integer, typename _Tp,
	   typename _BinaryPredicate, typename _IteratorTag>
    inline _FIterator
    __search_n_switch(_FIterator __begin, _FIterator __end, _Integer __count,
		      const _Tp& __val, _BinaryPredicate __binary_pred,
		      _IteratorTag)
    { return _GLIBCXX_STD_A::search_n(__begin, __end, __count, __val,
				      __binary_pred); }

  // Public interface.
  template<typename _FIterator, typename _Integer, typename _Tp,
	   typename _BinaryPredicate>
    inline _FIterator
    search_n(_FIterator __begin, _FIterator __end, _Integer __count,
	     const _Tp& __val, _BinaryPredicate __binary_pred)
    {
      return __search_n_switch(__begin, __end, __count, __val, __binary_pred,
			       std::__iterator_category(__begin));
    }


  // Sequential fallback.
  template<typename _IIter, typename _OutputIterator,
	   typename _UnaryOperation>
    inline _OutputIterator
    transform(_IIter __begin, _IIter __end, _OutputIterator __result,
	      _UnaryOperation __unary_op, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::transform(__begin, __end, __result, __unary_op); }

  // Parallel unary transform for random access iterators.
  template<typename _RAIter1, typename _RAIter2,
	   typename _UnaryOperation>
    _RAIter2
    __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
			_RAIter2 __result, _UnaryOperation __unary_op,
			random_access_iterator_tag, random_access_iterator_tag,
			__gnu_parallel::_Parallelism __parallelism_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().transform_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  bool __dummy = true;
	  typedef __gnu_parallel::_IteratorPair<_RAIter1,
	    _RAIter2, random_access_iterator_tag> _ItTrip;
	  _ItTrip __begin_pair(__begin, __result),
		  __end_pair(__end, __result + (__end - __begin));
	  __gnu_parallel::__transform1_selector<_ItTrip> __functionality;
	  __gnu_parallel::
	    __for_each_template_random_access(
	      __begin_pair, __end_pair, __unary_op, __functionality,
	      __gnu_parallel::_DummyReduct(),
	      __dummy, __dummy, -1, __parallelism_tag);
	  return __functionality._M_finish_iterator;
	}
      else
	return transform(__begin, __end, __result, __unary_op,
			 __gnu_parallel::sequential_tag());
    }

  // Sequential fallback for input iterator case.
  template<typename _RAIter1, typename _RAIter2,
	   typename _UnaryOperation, typename _IteratorTag1,
	   typename _IteratorTag2>
    inline _RAIter2
    __transform1_switch(_RAIter1 __begin, _RAIter1 __end,
			_RAIter2 __result, _UnaryOperation __unary_op,
			_IteratorTag1, _IteratorTag2)
    { return transform(__begin, __end, __result, __unary_op,
		       __gnu_parallel::sequential_tag()); }

  // Public interface.
  template<typename _IIter, typename _OutputIterator,
	   typename _UnaryOperation>
    inline _OutputIterator
    transform(_IIter __begin, _IIter __end, _OutputIterator __result,
	      _UnaryOperation __unary_op,
	      __gnu_parallel::_Parallelism __parallelism_tag)
    {
      return __transform1_switch(__begin, __end, __result, __unary_op,
				 std::__iterator_category(__begin),
				 std::__iterator_category(__result),
				 __parallelism_tag);
    }

  template<typename _IIter, typename _OutputIterator,
	   typename _UnaryOperation>
    inline _OutputIterator
    transform(_IIter __begin, _IIter __end, _OutputIterator __result,
	      _UnaryOperation __unary_op)
    {
      return __transform1_switch(__begin, __end, __result, __unary_op,
				 std::__iterator_category(__begin),
				 std::__iterator_category(__result));
    }


  // Sequential fallback
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _BinaryOperation>
    inline _OutputIterator
    transform(_IIter1 __begin1, _IIter1 __end1,
	      _IIter2 __begin2, _OutputIterator __result,
	      _BinaryOperation __binary_op, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::transform(__begin1, __end1,
				       __begin2, __result, __binary_op); }

  // Parallel binary transform for random access iterators.
  template<typename _RAIter1, typename _RAIter2,
	   typename _RAIter3, typename _BinaryOperation>
    _RAIter3
    __transform2_switch(_RAIter1 __begin1, _RAIter1 __end1,
			_RAIter2 __begin2,
			_RAIter3 __result, _BinaryOperation __binary_op,
			random_access_iterator_tag, random_access_iterator_tag,
			random_access_iterator_tag,
			__gnu_parallel::_Parallelism __parallelism_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    (__end1 - __begin1) >=
		__gnu_parallel::_Settings::get().transform_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  bool __dummy = true;
	  typedef __gnu_parallel::_IteratorTriple<_RAIter1,
	    _RAIter2, _RAIter3,
	    random_access_iterator_tag> _ItTrip;
	  _ItTrip __begin_triple(__begin1, __begin2, __result),
	    __end_triple(__end1, __begin2 + (__end1 - __begin1),
		       __result + (__end1 - __begin1));
	  __gnu_parallel::__transform2_selector<_ItTrip> __functionality;
	  __gnu_parallel::
	    __for_each_template_random_access(__begin_triple, __end_triple,
					      __binary_op, __functionality,
					      __gnu_parallel::_DummyReduct(),
					      __dummy, __dummy, -1,
					      __parallelism_tag);
	  return __functionality._M_finish_iterator;
	}
      else
	return transform(__begin1, __end1, __begin2, __result, __binary_op,
			 __gnu_parallel::sequential_tag());
    }

  // Sequential fallback for input iterator case.
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _BinaryOperation,
	   typename _Tag1, typename _Tag2, typename _Tag3>
    inline _OutputIterator
    __transform2_switch(_IIter1 __begin1, _IIter1 __end1,
			_IIter2 __begin2, _OutputIterator __result,
			_BinaryOperation __binary_op, _Tag1, _Tag2, _Tag3)
    { return transform(__begin1, __end1, __begin2, __result, __binary_op,
		       __gnu_parallel::sequential_tag()); }

  // Public interface.
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _BinaryOperation>
    inline _OutputIterator
    transform(_IIter1 __begin1, _IIter1 __end1,
	      _IIter2 __begin2, _OutputIterator __result,
	      _BinaryOperation __binary_op,
	      __gnu_parallel::_Parallelism __parallelism_tag)
    {
      return __transform2_switch(
	       __begin1, __end1, __begin2, __result, __binary_op,
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__result),
	       __parallelism_tag);
    }

  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _BinaryOperation>
    inline _OutputIterator
    transform(_IIter1 __begin1, _IIter1 __end1,
	      _IIter2 __begin2, _OutputIterator __result,
	      _BinaryOperation __binary_op)
    {
      return __transform2_switch(
	       __begin1, __end1, __begin2, __result, __binary_op,
	       std::__iterator_category(__begin1),
	       std::__iterator_category(__begin2),
	       std::__iterator_category(__result));
    }

  // Sequential fallback
  template<typename _FIterator, typename _Tp>
    inline void
    replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
	    const _Tp& __new_value, __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::replace(__begin, __end, __old_value, __new_value); }

  // Sequential fallback for input iterator case
  template<typename _FIterator, typename _Tp, typename _IteratorTag>
    inline void
    __replace_switch(_FIterator __begin, _FIterator __end,
		     const _Tp& __old_value, const _Tp& __new_value,
		     _IteratorTag)
    { replace(__begin, __end, __old_value, __new_value,
	      __gnu_parallel::sequential_tag()); }

  // Parallel replace for random access iterators
  template<typename _RAIter, typename _Tp>
    inline void
    __replace_switch(_RAIter __begin, _RAIter __end,
		     const _Tp& __old_value, const _Tp& __new_value,
		     random_access_iterator_tag,
		     __gnu_parallel::_Parallelism __parallelism_tag)
    {
      // XXX parallel version is where?
      replace(__begin, __end, __old_value, __new_value,
	      __gnu_parallel::sequential_tag());
    }

  // Public interface
  template<typename _FIterator, typename _Tp>
    inline void
    replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
	    const _Tp& __new_value,
	    __gnu_parallel::_Parallelism __parallelism_tag)
    {
      __replace_switch(__begin, __end, __old_value, __new_value,
		       std::__iterator_category(__begin),
		       __parallelism_tag);
    }

  template<typename _FIterator, typename _Tp>
    inline void
    replace(_FIterator __begin, _FIterator __end, const _Tp& __old_value,
	    const _Tp& __new_value)
    {
      __replace_switch(__begin, __end, __old_value, __new_value,
		       std::__iterator_category(__begin));
    }


  // Sequential fallback
  template<typename _FIterator, typename _Predicate, typename _Tp>
    inline void
    replace_if(_FIterator __begin, _FIterator __end, _Predicate __pred,
	       const _Tp& __new_value, __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::replace_if(__begin, __end, __pred, __new_value); }

  // Sequential fallback for input iterator case
  template<typename _FIterator, typename _Predicate, typename _Tp,
	   typename _IteratorTag>
    inline void
    __replace_if_switch(_FIterator __begin, _FIterator __end,
			_Predicate __pred, const _Tp& __new_value, _IteratorTag)
    { replace_if(__begin, __end, __pred, __new_value,
		 __gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators.
  template<typename _RAIter, typename _Predicate, typename _Tp>
    void
    __replace_if_switch(_RAIter __begin, _RAIter __end,
			_Predicate __pred, const _Tp& __new_value,
			random_access_iterator_tag,
			__gnu_parallel::_Parallelism __parallelism_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().replace_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  bool __dummy;
	  __gnu_parallel::
	    __replace_if_selector<_RAIter, _Predicate, _Tp>
	    __functionality(__new_value);
	  __gnu_parallel::
	    __for_each_template_random_access(
	      __begin, __end, __pred, __functionality,
	      __gnu_parallel::_DummyReduct(),
	      true, __dummy, -1, __parallelism_tag);
	}
      else
	replace_if(__begin, __end, __pred, __new_value,
		   __gnu_parallel::sequential_tag());
    }

  // Public interface.
  template<typename _FIterator, typename _Predicate, typename _Tp>
    inline void
    replace_if(_FIterator __begin, _FIterator __end,
	       _Predicate __pred, const _Tp& __new_value,
	       __gnu_parallel::_Parallelism __parallelism_tag)
    {
      __replace_if_switch(__begin, __end, __pred, __new_value,
			  std::__iterator_category(__begin),
			  __parallelism_tag);
    }

  template<typename _FIterator, typename _Predicate, typename _Tp>
    inline void
    replace_if(_FIterator __begin, _FIterator __end,
	       _Predicate __pred, const _Tp& __new_value)
    {
      __replace_if_switch(__begin, __end, __pred, __new_value,
			  std::__iterator_category(__begin));
    }

  // Sequential fallback
  template<typename _FIterator, typename _Generator>
    inline void
    generate(_FIterator __begin, _FIterator __end, _Generator __gen,
	     __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::generate(__begin, __end, __gen); }

  // Sequential fallback for input iterator case.
  template<typename _FIterator, typename _Generator, typename _IteratorTag>
    inline void
    __generate_switch(_FIterator __begin, _FIterator __end, _Generator __gen,
		      _IteratorTag)
    { generate(__begin, __end, __gen, __gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators.
  template<typename _RAIter, typename _Generator>
    void
    __generate_switch(_RAIter __begin, _RAIter __end,
		      _Generator __gen, random_access_iterator_tag,
		      __gnu_parallel::_Parallelism __parallelism_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().generate_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  bool __dummy;
	  __gnu_parallel::__generate_selector<_RAIter>
	    __functionality;
	  __gnu_parallel::
	    __for_each_template_random_access(
	      __begin, __end, __gen, __functionality,
	      __gnu_parallel::_DummyReduct(),
	      true, __dummy, -1, __parallelism_tag);
	}
      else
	generate(__begin, __end, __gen, __gnu_parallel::sequential_tag());
    }

  // Public interface.
  template<typename _FIterator, typename _Generator>
    inline void
    generate(_FIterator __begin, _FIterator __end,
	     _Generator __gen, __gnu_parallel::_Parallelism __parallelism_tag)
    {
      __generate_switch(__begin, __end, __gen,
			std::__iterator_category(__begin),
			__parallelism_tag);
    }

  template<typename _FIterator, typename _Generator>
    inline void
    generate(_FIterator __begin, _FIterator __end, _Generator __gen)
    {
      __generate_switch(__begin, __end, __gen,
			std::__iterator_category(__begin));
    }


  // Sequential fallback.
  template<typename _OutputIterator, typename _Size, typename _Generator>
    inline _OutputIterator
    generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
	       __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::generate_n(__begin, __n, __gen); }

  // Sequential fallback for input iterator case.
  template<typename _OutputIterator, typename _Size, typename _Generator,
	   typename _IteratorTag>
    inline _OutputIterator
    __generate_n_switch(_OutputIterator __begin, _Size __n, _Generator __gen,
			_IteratorTag)
    { return generate_n(__begin, __n, __gen,
			__gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators.
  template<typename _RAIter, typename _Size, typename _Generator>
    inline _RAIter
    __generate_n_switch(_RAIter __begin, _Size __n, _Generator __gen,
			random_access_iterator_tag,
			__gnu_parallel::_Parallelism __parallelism_tag)
    {
      // XXX parallel version is where?
      return generate_n(__begin, __n, __gen, __gnu_parallel::sequential_tag());
    }

  // Public interface.
  template<typename _OutputIterator, typename _Size, typename _Generator>
    inline _OutputIterator
    generate_n(_OutputIterator __begin, _Size __n, _Generator __gen,
	       __gnu_parallel::_Parallelism __parallelism_tag)
    {
      return __generate_n_switch(__begin, __n, __gen,
				 std::__iterator_category(__begin),
				 __parallelism_tag);
    }

  template<typename _OutputIterator, typename _Size, typename _Generator>
    inline _OutputIterator
    generate_n(_OutputIterator __begin, _Size __n, _Generator __gen)
    {
      return __generate_n_switch(__begin, __n, __gen,
				 std::__iterator_category(__begin));
    }


  // Sequential fallback.
  template<typename _RAIter>
    inline void
    random_shuffle(_RAIter __begin, _RAIter __end,
		   __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::random_shuffle(__begin, __end); }

  // Sequential fallback.
  template<typename _RAIter, typename _RandomNumberGenerator>
    inline void
    random_shuffle(_RAIter __begin, _RAIter __end,
		   _RandomNumberGenerator& __rand,
		   __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::random_shuffle(__begin, __end, __rand); }


  /** @brief Functor wrapper for std::rand(). */
  template<typename _MustBeInt = int>
    struct _CRandNumber
    {
      int
      operator()(int __limit)
      { return rand() % __limit; }
    };

  // Fill in random number generator.
  template<typename _RAIter>
    inline void
    random_shuffle(_RAIter __begin, _RAIter __end)
    {
      _CRandNumber<> __r;
      // Parallelization still possible.
      __gnu_parallel::random_shuffle(__begin, __end, __r);
    }

  // Parallel algorithm for random access iterators.
  template<typename _RAIter, typename _RandomNumberGenerator>
    void
    random_shuffle(_RAIter __begin, _RAIter __end,
#if __cplusplus >= 201103L
		   _RandomNumberGenerator&& __rand)
#else
		   _RandomNumberGenerator& __rand)
#endif
    {
      if (__begin == __end)
	return;
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().random_shuffle_minimal_n))
	__gnu_parallel::__parallel_random_shuffle(__begin, __end, __rand);
      else
	__gnu_parallel::__sequential_random_shuffle(__begin, __end, __rand);
    }

  // Sequential fallback.
  template<typename _FIterator, typename _Predicate>
    inline _FIterator
    partition(_FIterator __begin, _FIterator __end,
	      _Predicate __pred, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::partition(__begin, __end, __pred); }

  // Sequential fallback for input iterator case.
  template<typename _FIterator, typename _Predicate, typename _IteratorTag>
    inline _FIterator
    __partition_switch(_FIterator __begin, _FIterator __end,
		       _Predicate __pred, _IteratorTag)
    { return partition(__begin, __end, __pred,
		       __gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators.
  template<typename _RAIter, typename _Predicate>
    _RAIter
    __partition_switch(_RAIter __begin, _RAIter __end,
		       _Predicate __pred, random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().partition_minimal_n))
	{
	  typedef typename std::iterator_traits<_RAIter>::
	    difference_type _DifferenceType;
	  _DifferenceType __middle = __gnu_parallel::
	    __parallel_partition(__begin, __end, __pred,
			       __gnu_parallel::__get_max_threads());
	  return __begin + __middle;
	}
      else
	return partition(__begin, __end, __pred,
			 __gnu_parallel::sequential_tag());
    }

  // Public interface.
  template<typename _FIterator, typename _Predicate>
    inline _FIterator
    partition(_FIterator __begin, _FIterator __end, _Predicate __pred)
    {
      return __partition_switch(__begin, __end, __pred,
				std::__iterator_category(__begin));
    }

  // sort interface

  // Sequential fallback
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end,
	 __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::sort(__begin, __end); }

  // Sequential fallback
  template<typename _RAIter, typename _Compare>
    inline void
    sort(_RAIter __begin, _RAIter __end, _Compare __comp,
	 __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::sort<_RAIter, _Compare>(__begin, __end,
							     __comp); }

  // Public interface
  template<typename _RAIter, typename _Compare,
	   typename _Parallelism>
    void
    sort(_RAIter __begin, _RAIter __end, _Compare __comp,
	 _Parallelism __parallelism)
  {
    typedef typename iterator_traits<_RAIter>::value_type _ValueType;

    if (__begin != __end)
      {
	if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
	      __gnu_parallel::_Settings::get().sort_minimal_n))
	  __gnu_parallel::__parallel_sort<false>(
			    __begin, __end, __comp, __parallelism);
	else
	  sort(__begin, __end, __comp, __gnu_parallel::sequential_tag());
      }
  }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, std::less<_ValueType>(),
	   __gnu_parallel::default_parallel_tag());
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end,
	 __gnu_parallel::default_parallel_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end,
	 __gnu_parallel::parallel_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end,
	 __gnu_parallel::multiway_mergesort_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end,
	 __gnu_parallel::multiway_mergesort_sampling_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end,
	 __gnu_parallel::multiway_mergesort_exact_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end,
	 __gnu_parallel::quicksort_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    sort(_RAIter __begin, _RAIter __end,
	 __gnu_parallel::balanced_quicksort_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface
  template<typename _RAIter, typename _Compare>
    void
    sort(_RAIter __begin, _RAIter __end, _Compare __comp)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      sort(__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
    }

  // stable_sort interface


  // Sequential fallback
  template<typename _RAIter>
    inline void
    stable_sort(_RAIter __begin, _RAIter __end,
		__gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::stable_sort(__begin, __end); }

  // Sequential fallback
  template<typename _RAIter, typename _Compare>
    inline void
    stable_sort(_RAIter __begin, _RAIter __end,
		_Compare __comp, __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::stable_sort<_RAIter, _Compare>(__begin, __end, __comp); }

  // Public interface
  template<typename _RAIter, typename _Compare,
	   typename _Parallelism>
    void
    stable_sort(_RAIter __begin, _RAIter __end,
		_Compare __comp, _Parallelism __parallelism)
    {
      typedef iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;

      if (__begin != __end)
	{
	  if (_GLIBCXX_PARALLEL_CONDITION(
		static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin) >=
		__gnu_parallel::_Settings::get().sort_minimal_n))
	    __gnu_parallel::__parallel_sort<true>(__begin, __end,
						  __comp, __parallelism);
	  else
	    stable_sort(__begin, __end, __comp,
			__gnu_parallel::sequential_tag());
	}
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    stable_sort(_RAIter __begin, _RAIter __end)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      stable_sort(__begin, __end, std::less<_ValueType>(),
		  __gnu_parallel::default_parallel_tag());
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    stable_sort(_RAIter __begin, _RAIter __end,
		__gnu_parallel::default_parallel_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    stable_sort(_RAIter __begin, _RAIter __end,
		__gnu_parallel::parallel_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    stable_sort(_RAIter __begin, _RAIter __end,
		__gnu_parallel::multiway_mergesort_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    stable_sort(_RAIter __begin, _RAIter __end,
		__gnu_parallel::quicksort_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    stable_sort(_RAIter __begin, _RAIter __end,
		__gnu_parallel::balanced_quicksort_tag __parallelism)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      stable_sort(__begin, __end, std::less<_ValueType>(), __parallelism);
    }

  // Public interface
  template<typename _RAIter, typename _Compare>
    void
    stable_sort(_RAIter __begin, _RAIter __end, _Compare __comp)
    {
      stable_sort(
	__begin, __end, __comp, __gnu_parallel::default_parallel_tag());
    }

  // Sequential fallback
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
	  _IIter2 __end2, _OutputIterator __result,
	  __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::merge(
	       __begin1, __end1, __begin2, __end2, __result); }

  // Sequential fallback
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Compare>
    inline _OutputIterator
    merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
	  _IIter2 __end2, _OutputIterator __result, _Compare __comp,
	  __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::merge(
		__begin1, __end1, __begin2, __end2, __result, __comp); }

  // Sequential fallback for input iterator case
  template<typename _IIter1, typename _IIter2, typename _OutputIterator,
	   typename _Compare, typename _IteratorTag1,
	   typename _IteratorTag2, typename _IteratorTag3>
    inline _OutputIterator
    __merge_switch(_IIter1 __begin1, _IIter1 __end1,
		   _IIter2 __begin2, _IIter2 __end2,
		   _OutputIterator __result, _Compare __comp,
		   _IteratorTag1, _IteratorTag2, _IteratorTag3)
     { return _GLIBCXX_STD_A::merge(__begin1, __end1, __begin2, __end2,
				    __result, __comp); }

  // Parallel algorithm for random access iterators
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Compare>
    _OutputIterator
    __merge_switch(_IIter1 __begin1, _IIter1 __end1,
		   _IIter2 __begin2, _IIter2 __end2,
		   _OutputIterator __result, _Compare __comp,
		   random_access_iterator_tag, random_access_iterator_tag,
		   random_access_iterator_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    (static_cast<__gnu_parallel::_SequenceIndex>(__end1 - __begin1)
	     >= __gnu_parallel::_Settings::get().merge_minimal_n
	     || static_cast<__gnu_parallel::_SequenceIndex>(__end2 - __begin2)
	     >= __gnu_parallel::_Settings::get().merge_minimal_n)))
	return __gnu_parallel::__parallel_merge_advance(
		 __begin1, __end1, __begin2, __end2, __result,
		 (__end1 - __begin1) + (__end2 - __begin2), __comp);
      else
	return __gnu_parallel::__merge_advance(
		 __begin1, __end1, __begin2, __end2, __result,
		 (__end1 - __begin1) + (__end2 - __begin2), __comp);
  }

  // Public interface
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator, typename _Compare>
    inline _OutputIterator
    merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
	  _IIter2 __end2, _OutputIterator __result, _Compare __comp)
    {
      return __merge_switch(
		__begin1, __end1, __begin2, __end2, __result, __comp,
		std::__iterator_category(__begin1),
		std::__iterator_category(__begin2),
		std::__iterator_category(__result));
  }

  // Public interface, insert default comparator
  template<typename _IIter1, typename _IIter2,
	   typename _OutputIterator>
    inline _OutputIterator
    merge(_IIter1 __begin1, _IIter1 __end1, _IIter2 __begin2,
	  _IIter2 __end2, _OutputIterator __result)
    {
      typedef typename std::iterator_traits<_IIter1>::value_type _ValueType1;
      typedef typename std::iterator_traits<_IIter2>::value_type _ValueType2;

      return __gnu_parallel::merge(__begin1, __end1, __begin2, __end2,
		__result, __gnu_parallel::_Less<_ValueType1, _ValueType2>());
    }

  // Sequential fallback
  template<typename _RAIter>
    inline void
    nth_element(_RAIter __begin, _RAIter __nth,
		_RAIter __end, __gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end); }

  // Sequential fallback
  template<typename _RAIter, typename _Compare>
    inline void
    nth_element(_RAIter __begin, _RAIter __nth,
		_RAIter __end, _Compare __comp,
		__gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::nth_element(__begin, __nth, __end, __comp); }

  // Public interface
  template<typename _RAIter, typename _Compare>
    inline void
    nth_element(_RAIter __begin, _RAIter __nth,
		_RAIter __end, _Compare __comp)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().nth_element_minimal_n))
	__gnu_parallel::__parallel_nth_element(__begin, __nth, __end, __comp);
      else
	nth_element(__begin, __nth, __end, __comp,
		    __gnu_parallel::sequential_tag());
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    nth_element(_RAIter __begin, _RAIter __nth,
		_RAIter __end)
    {
      typedef typename iterator_traits<_RAIter>::value_type _ValueType;
      __gnu_parallel::nth_element(__begin, __nth, __end,
				  std::less<_ValueType>());
    }

  // Sequential fallback
  template<typename _RAIter, typename _Compare>
    inline void
    partial_sort(_RAIter __begin, _RAIter __middle,
		 _RAIter __end, _Compare __comp,
		 __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end, __comp); }

  // Sequential fallback
  template<typename _RAIter>
    inline void
    partial_sort(_RAIter __begin, _RAIter __middle,
		 _RAIter __end, __gnu_parallel::sequential_tag)
    { _GLIBCXX_STD_A::partial_sort(__begin, __middle, __end); }

  // Public interface, parallel algorithm for random access iterators
  template<typename _RAIter, typename _Compare>
    void
    partial_sort(_RAIter __begin, _RAIter __middle,
		 _RAIter __end, _Compare __comp)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().partial_sort_minimal_n))
	__gnu_parallel::
	  __parallel_partial_sort(__begin, __middle, __end, __comp);
      else
	partial_sort(__begin, __middle, __end, __comp,
		     __gnu_parallel::sequential_tag());
    }

  // Public interface, insert default comparator
  template<typename _RAIter>
    inline void
    partial_sort(_RAIter __begin, _RAIter __middle,
		 _RAIter __end)
    {
      typedef iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;
      __gnu_parallel::partial_sort(__begin, __middle, __end,
				   std::less<_ValueType>());
    }

  // Sequential fallback
  template<typename _FIterator>
    inline _FIterator
    max_element(_FIterator __begin, _FIterator __end,
		__gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::max_element(__begin, __end); }

  // Sequential fallback
  template<typename _FIterator, typename _Compare>
    inline _FIterator
    max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
		__gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::max_element(__begin, __end, __comp); }

  // Sequential fallback for input iterator case
  template<typename _FIterator, typename _Compare, typename _IteratorTag>
    inline _FIterator
    __max_element_switch(_FIterator __begin, _FIterator __end,
		       _Compare __comp, _IteratorTag)
    { return max_element(__begin, __end, __comp,
			 __gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators
  template<typename _RAIter, typename _Compare>
    _RAIter
    __max_element_switch(_RAIter __begin, _RAIter __end,
			 _Compare __comp, random_access_iterator_tag,
			 __gnu_parallel::_Parallelism __parallelism_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().max_element_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  _RAIter __res(__begin);
	  __gnu_parallel::__identity_selector<_RAIter>
	    __functionality;
	  __gnu_parallel::
	    __for_each_template_random_access(
	      __begin, __end, __gnu_parallel::_Nothing(), __functionality,
	      __gnu_parallel::__max_element_reduct<_Compare, _RAIter>(__comp),
	      __res, __res, -1, __parallelism_tag);
	  return __res;
	}
      else
	return max_element(__begin, __end, __comp,
			   __gnu_parallel::sequential_tag());
    }

  // Public interface, insert default comparator
  template<typename _FIterator>
    inline _FIterator
    max_element(_FIterator __begin, _FIterator __end,
		__gnu_parallel::_Parallelism __parallelism_tag)
    {
      typedef typename iterator_traits<_FIterator>::value_type _ValueType;
      return max_element(__begin, __end, std::less<_ValueType>(),
			 __parallelism_tag);
    }

  template<typename _FIterator>
    inline _FIterator
    max_element(_FIterator __begin, _FIterator __end)
    {
      typedef typename iterator_traits<_FIterator>::value_type _ValueType;
      return __gnu_parallel::max_element(__begin, __end,
					 std::less<_ValueType>());
    }

  // Public interface
  template<typename _FIterator, typename _Compare>
    inline _FIterator
    max_element(_FIterator __begin, _FIterator __end, _Compare __comp,
		__gnu_parallel::_Parallelism __parallelism_tag)
    {
      return __max_element_switch(__begin, __end, __comp,
				  std::__iterator_category(__begin),
				  __parallelism_tag);
    }

  template<typename _FIterator, typename _Compare>
    inline _FIterator
    max_element(_FIterator __begin, _FIterator __end, _Compare __comp)
    {
      return __max_element_switch(__begin, __end, __comp,
				  std::__iterator_category(__begin));
    }


  // Sequential fallback
  template<typename _FIterator>
    inline _FIterator
    min_element(_FIterator __begin, _FIterator __end,
		__gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::min_element(__begin, __end); }

  // Sequential fallback
  template<typename _FIterator, typename _Compare>
    inline _FIterator
    min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
		__gnu_parallel::sequential_tag)
    { return _GLIBCXX_STD_A::min_element(__begin, __end, __comp); }

  // Sequential fallback for input iterator case
  template<typename _FIterator, typename _Compare, typename _IteratorTag>
    inline _FIterator
    __min_element_switch(_FIterator __begin, _FIterator __end,
		       _Compare __comp, _IteratorTag)
    { return min_element(__begin, __end, __comp,
			 __gnu_parallel::sequential_tag()); }

  // Parallel algorithm for random access iterators
  template<typename _RAIter, typename _Compare>
    _RAIter
    __min_element_switch(_RAIter __begin, _RAIter __end,
			 _Compare __comp, random_access_iterator_tag,
			 __gnu_parallel::_Parallelism __parallelism_tag)
    {
      if (_GLIBCXX_PARALLEL_CONDITION(
	    static_cast<__gnu_parallel::_SequenceIndex>(__end - __begin)
	    >= __gnu_parallel::_Settings::get().min_element_minimal_n
	    && __gnu_parallel::__is_parallel(__parallelism_tag)))
	{
	  _RAIter __res(__begin);
	  __gnu_parallel::__identity_selector<_RAIter>
	    __functionality;
	  __gnu_parallel::
	    __for_each_template_random_access(
	      __begin, __end, __gnu_parallel::_Nothing(), __functionality,
	      __gnu_parallel::__min_element_reduct<_Compare, _RAIter>(__comp),
	      __res, __res, -1, __parallelism_tag);
	  return __res;
	}
      else
	return min_element(__begin, __end, __comp,
			   __gnu_parallel::sequential_tag());
    }

  // Public interface, insert default comparator
  template<typename _FIterator>
    inline _FIterator
    min_element(_FIterator __begin, _FIterator __end,
		__gnu_parallel::_Parallelism __parallelism_tag)
    {
      typedef typename iterator_traits<_FIterator>::value_type _ValueType;
      return min_element(__begin, __end, std::less<_ValueType>(),
			 __parallelism_tag);
    }

  template<typename _FIterator>
    inline _FIterator
    min_element(_FIterator __begin, _FIterator __end)
    {
      typedef typename iterator_traits<_FIterator>::value_type _ValueType;
      return __gnu_parallel::min_element(__begin, __end,
					 std::less<_ValueType>());
    }

  // Public interface
  template<typename _FIterator, typename _Compare>
    inline _FIterator
    min_element(_FIterator __begin, _FIterator __end, _Compare __comp,
		__gnu_parallel::_Parallelism __parallelism_tag)
    {
      return __min_element_switch(__begin, __end, __comp,
				  std::__iterator_category(__begin),
				  __parallelism_tag);
    }

  template<typename _FIterator, typename _Compare>
    inline _FIterator
    min_element(_FIterator __begin, _FIterator __end, _Compare __comp)
    {
      return __min_element_switch(__begin, __end, __comp,
				  std::__iterator_category(__begin));
    }

#if __cplusplus >= 201703L
  using _GLIBCXX_STD_A::for_each_n;
  using _GLIBCXX_STD_A::sample;
#endif
} // end namespace
} // end namespace

#endif /* _GLIBCXX_PARALLEL_ALGO_H */
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   (                 (                 (                                                                        (                 (                 (                                        (    0  8  @  8  0  (                     @  8  0  (                                                                              (                 (                 (                 (                            (  @  (                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        m    __fentry__                                              9[    __x86_return_thunk                                      k    __mhi_driver_register                                   @    __dev_kfree_skb_any                                     2tc    mhi_queue_is_full                                       a    netif_tx_wake_queue                                     @    unregister_netdev                                        e(    mhi_unprepare_from_transfer                             j    kfree_skb_reason                                        m    free_netdev                                             R    alloc_netdev_mqs                                        j    delayed_work_timer_fn                                   9c    init_timer_key                                          9    mhi_prepare_for_transfer                                1$    mhi_get_free_desc_count                                 xB<    register_netdev                                         ;    mhi_driver_unregister                                       mhi_queue_skb                                           P    jiffies                                                 ;    net_ratelimit                                           ~    _printk                                                 #    __netdev_alloc_skb                                      Qs    __SCT__cond_resched                                     Ӆ3-    system_wq                                               m    queue_delayed_work_on                                   I    netif_carrier_on                                            netif_carrier_off                                       J    cancel_delayed_work_sync                                S>    skb_put                                                 plk    __netif_rx                                              ;.	B    netdev_printk                                           zR    module_layout                                                                                                                                                                                                                                                                                                                                   mhi_net                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0                      
9             X               
Y A= 	     N=     Z=    n=    =    =    =    =    =    =    =      =    =    >    >      >     +>    A>      L> `     T> b @   h  *      L>       [  k       V     @   -  W      4&  Q             _ \>               a j>      x>        >        >      >     >    >    >    >    >    >    >    ?    ?    2? 	   G? 
   R? 
     \?     l?    |?    ?    ?    ?    ?    ?    ?    ?    ? G  P  ?       	@ h @   ֤	        k      @ k      @ k   @  @ k     "@ W     -@ W      7@    @  @@      J@ Q     T@ Q      ]@ Q   @  e@ Q     m@ i   w@ i    @ k @  @ `     i        @ *   @  @ *   `  @ *     @ *     h *     @ *     ? *      w *       *   @  ' *   `  @     @ m   @ o   @ q  	  @ G  @	  A ,  @
  o *   
   *   
  A *   
   d 
   e    A ]      A ]   @  +A *   `  .A *     1A *     4A `     p *  @  DA *  `  j> c   JA Q    TA S  
  ^A D     jA t   tA v    }A v @  A x   A z   A x    A ~ @  A             B x @  u Q     ,       A K     A K     A K     C       
 *   @  A 
     x        V     @   A s    A k     B k    :"    @  ? ]   B      B      A *            g        ^ @               j @               l @               n @               p       
        s     [        f        r       
        s     K          u       
        s        w       
       s        y       
       s     |        } B               {       
        s     |               
       s     k                        
        s     k       *           +B   (   
 r6      v              
         9B      ] k       DB Q   @   uA  D     PB       cB               @         nB     yB     jA  @  u            
       h                    
        h               
        h                            
        h     [         B 	  8   O       e   @   w      Z      n         @       B     B     B 	     B h     1 %  @   B      B      B R     0     B *     B      
      B      B               
                          
                         C       C    p         
    	@ h .C           
   	@ h x    =C     KC            
    	@ h bC  jC     ~C           
  C     C     C           
    1 %  0  
  C           
}	     1 %  C     C     C     mhi_callback MHI_CB_IDLE MHI_CB_PENDING_DATA MHI_CB_LPM_ENTER MHI_CB_LPM_EXIT MHI_CB_EE_RDDM MHI_CB_EE_MISSION_MODE MHI_CB_SYS_ERROR MHI_CB_FATAL_ERROR MHI_CB_BW_REQ mhi_flags MHI_EOB MHI_EOT MHI_CHAIN mhi_device_type MHI_DEVICE_XFER MHI_DEVICE_CONTROLLER image_info mhi_buf bhi_vec bhi_vec_entry mhi_link_info target_link_speed target_link_width mhi_ee_type MHI_EE_PBL MHI_EE_SBL MHI_EE_AMSS MHI_EE_RDDM MHI_EE_WFW MHI_EE_PTHRU MHI_EE_EDL MHI_EE_FP MHI_EE_MAX_SUPPORTED MHI_EE_DISABLE_TRANSITION MHI_EE_NOT_SUPPORTED MHI_EE_MAX mhi_state MHI_STATE_RESET MHI_STATE_READY MHI_STATE_M0 MHI_STATE_M1 MHI_STATE_M2 MHI_STATE_M3 MHI_STATE_M3_FAST MHI_STATE_BHI MHI_STATE_SYS_ERR MHI_STATE_MAX mhi_controller cntrl_dev mhi_dev bhi bhie wake_db iova_start iova_stop fw_image edl_image rddm_size sbl_size seg_len reg_len fbc_image rddm_image mhi_chan lpm_chans max_chan total_ev_rings hw_ev_rings sw_ev_rings family_number oem_pk_hash mhi_event mhi_cmd mhi_ctxt pm_mutex pm_lock db_access dev_wake pending_pkts M0 M2 M3 transition_list wlock st_worker hiprio_wq state_event status_cb wake_get wake_put wake_toggle runtime_get runtime_put map_single unmap_single bounce_buf fbc_download wake_set mhi_device mhi_cntrl ul_chan dl_chan ul_chan_id dl_chan_id mhi_buf_info mhi_device_id mhi_result bytes_xferd transaction_status mhi_driver ul_xfer_cb dl_xfer_cb mhi_net_stats tx_syncp rx_syncp mhi_net_dev mdev skbagg_head skbagg_tail rx_refill rx_queue_sz msg_enable mhi_device_info netname mhi_net_driver_exit mhi_net_driver_init mhi_net_remove mhi_net_probe mhi_net_rx_refill_work mhi_res mhi_net_ul_callback mhi_net_dl_callback mhi_netdev mhi_net_skb_agg mhi_net_setup mhi_ndo_get_stats64 mhi_ndo_xmit mhi_ndo_stop mhi_ndo_open    mhi_net.ko  2                                                                                                   	                      
                                                                                                               Z                   k              +     |              B                    O                   h            	       ~            
                   <                                       $                    V            `       k                                     `                                                  0             3          P       B          +      P                 g                   {    @                	                   	                         B           @      ?                 2                             	 +       #                          #                  >    ,       .       T                                                  x                             x                                      #                                                                                                 %                     0                   <                                          M                     c                     q                                                                                                                                                                                                                                                            0            x       Y                     u                                                                                                                                                                                              __UNIQUE_ID_alias195 __UNIQUE_ID_alias194 __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 mhi_ndo_get_stats64 mhi_net_setup mhi_netdev_ops mhi_net_skb_agg mhi_net_driver_init mhi_net_driver mhi_net_ul_callback mhi_net_remove mhi_net_probe mhi_net_rx_refill_work mhi_net_driver_exit mhi_ndo_xmit mhi_ndo_xmit.cold mhi_net_rx_refill_work.cold mhi_ndo_open mhi_ndo_stop mhi_net_dl_callback __print_once.0 mhi_net_dl_callback.cold __UNIQUE_ID_license378 __UNIQUE_ID_description377 __UNIQUE_ID_author376 __UNIQUE_ID___addressable_cleanup_module375 __UNIQUE_ID___addressable_init_module374 mhi_net_id_table mhi_hwip0 mhi_swip0 skb_put __this_module unregister_netdev cleanup_module mhi_queue_is_full net_ratelimit __fentry__ init_module alloc_netdev_mqs queue_delayed_work_on mhi_queue_skb kfree_skb_reason netdev_printk free_netdev netif_tx_wake_queue __x86_return_thunk __netdev_alloc_skb jiffies cancel_delayed_work_sync init_timer_key mhi_driver_unregister __dev_kfree_skb_any __mod_mhi__mhi_net_id_table_device_table mhi_unprepare_from_transfer netif_carrier_off __netif_rx delayed_work_timer_fn netif_carrier_on __SCT__cond_resched mhi_prepare_for_transfer mhi_get_free_desc_count __mhi_driver_register system_wq             5   R          @   a          5                                 @             5            @   ,         @   1         5   R         F            @            3            ?            5            1            H            ;            >            @            5   3            `       C         7            K                                      D            N            >            @            O   !         =   0         @   A         5   m         :   ~         3            @            B            @            4                        F            @            5   -         3   A         A   b         :   k         M   v         4                               ;            O            @            Q            9            5            Q            9            L   .         @   A         5   I         B   g         I   s         C   {         @            5            O            /            J   4         @   ;         Q   Q         9   a         	   h            '       u         /            F            F             5             0                                          P                                  E   	                               8                                   (       "          8   '                   2             P       9                     ?          	   E          <   J             h                                         `                                                              0      (                   0                   8             @      @                   H                   P             @      X                                                    "                   ^                           H             x       x                                                                        @                   @      @                                  Q                                                           +                                                                            /                          $                   (                   ,                   0             -      4             z      8             3                                         V                    `                                                            7                   9                   :                    >      $                   (                   ,                   0                   4                   8                   <                   @                   D                   H                   L                   P                   T                   X                   \             
      `                   d                   h             &      l             ;      p                   t                   x                   |             
                   -                   .                   /                   4                   ;                   @                   G                   R                   S                   W                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             $                  (                  ,                  0                  4                  8                  <                  @                  D                  H                  L            -      P            2      T            @      X            F      \            z      `                  d                  h                  l                  p                  t                  x            .      |            /                  1                  3                  8                  F                  L                  N                  P                  U                                                                                                                                                                                                                                                   +                   N                                                                                0                          0                    @          0                      2                      6                         j                M           8         6           P         2            .symtab .strtab .shstrtab .note.gnu.build-id .note.Linux .rela.text .rela.init.text .rela.exit.text .rela.text.unlikely .rela__mcount_loc .rodata.str1.8 .rela.smp_locks .rodata.str1.1 .modinfo .rela.rodata .rela.return_sites .orc_unwind .rela.orc_unwind_ip __versions .rela.data .rela.exit.data .rela.init.data .data.once .rela.static_call_sites .rela.gnu.linkonce.this_module .bss .comment .note.GNU-stack .BTF .gnu_debuglink                                                                                          @       $                              .                     d       <                              ?                                                         :      @               >            *                    J                     R                                    E      @               E      `       *                    Z                     j                                    U      @                F      0       *                    j                     v      N                              e      @               0F            *   	                 ~                           `                              y      @               8G             *                          2               (      w                                                                                            @               XH      H       *                          2                     !                                                                                                           	      P                                    @               H             *                                         
      <                                    @               `I      h      *                                         L
                                                                                                 @               J            *                                                                                                                                        
     @               U             *                                                                                 @               V             *                    -                                                        (     @               V             *                    8                                                        H                                                        C     @               V      0       *   !                 `                                         @               [     @               V      0       *   #                 z                                                              0                     P                                                                                                                                                                    1                                                          1            +   /                 	                      x9                                                         W                                   0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  Xy1En0ۜ="`OH,K&lL cpKD{_C/,}
8`>S8'VuM_=٬RJ T&rC7rjN&H$81t]N j=eS-Ov)zO[psnjMlsp[GmYMKZlOk(GdiSzI&JgyJp	mdUNz\(E          ~Module signature appended~
 070701000A03BD000081A4000000000000000000000001682F6DA700005773000000CA0000000200000000000000000000003900000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/mii.ko  ELF          >                    0M          @     @ " !          GNU 2}x?w&QĹ
        Linux                Linux   6.1.0-37-amd64      HOHG 7H    ΃@@D։փE։փE։ց    E։ց @  E	    f    AWAVAUATUHSLoHF  GFF <1҃  FFFF  7HG L    u    LAHE     AE   Lu 	   HE     Lu 
   AHE        HACCEtD	A   t CA   tKK@A C   C     1
   AV   HE1jCCEtCDC   @   @tD%    ঃdAADfC1fCDcE	ЈE[]A\A]A^A_       HDf
 fA E	S #S0t  A"d   At         SH7   HHC     %   t3H{   HC     0[    f         SH7   HHC     3H{   HC     [         SH71HHC     t3H{1҉HC(    1[    [             UHHSHHt    pf#3f3Hf#KfKH  t%I  t?G  t	[]    fHxH@     fC1[]    {;0tL@H@(L    1ftfu܉x3Kf pɃ	1@pt	fуPփ9tL@	ʉPLS3H@(    HZE    1Nf         AWAVAUATUHSHHGLoF	<FE1҈F
7AHG LA      3   LAHC     $C   L3	   HC     L3
   D$HC        HAAAπ  CtL$E  D	 AA   tBEA@$    E11E1
   Y   HE1j
  AA   uDE   @   @tD%    ঃdAE1ADDeH}0EC	DC    H}@D    H}PDH[]A\A]A^A_       HDf
ǃ fA E	ADD!@0t  Am@u
Ad   AGA	    AWAVAUATUSHDfLoeH%(   HD$1A
Ad!A   ]  ~HP  ~	F  v
H;77  AE<(  A     <   1HC L    р AdEʀ}u	A   SD	S9t3HC(1L    K1HT$eH+%(     H[]A\A]A^A_    G  <tHC 1L    @wHu@H|$D$        D$?G     3HC L    SAā  	   3HC L    SAAAL$ȃƃ@EƉ@΀EƉƁ   EƉƁ    EƉƁ   @E	ń   %   Ɓ    EA	A9t   3HC(L    Sk3E9ttHC(D	   L    31LHC     31LHC(    cUA9uE1E1;            AVAUIATAUSHGHX8    H9uu1   I}       AE     Au I}   IE     AEAu I}   IE     AAEui!Ӂ      E     uAE9eAE	ø   A][]A\A]A^        E    1
   Au I}IE     D!Ӂ      tU      t{En    A]"E    1wс   t>E:       uu@    t   @   1۾   1E            SH    H{HW8Htu
t[    [    u[        AWAVAUATUSHDfFLwAA	A
AAdA!A  A n  ~Ha  ~W  ~ M  vH9<  E<0  A    <   1HC L    р AdEʀ}u	A   SD	S9t3HC(1L    A   CD- DkAA	1DkH[]A\A]A^A_    E?     HC L    SAā"  E1E1uǃ@@Eǉ@π@Eǉǁ   @Eǉǁ       Eǉǁ    @  E	̈́   %    EA	A9t)DD$   3HC(L    SDD$k3E9ttHC(D	   L    31LHC     31LHC(    Gth<HC 1L    @IL$	   3LHC     SL$AAAA9%hJI}H               H    uA  t@d   I}EH            t	H    ɉÉH    1뺺  ź
   I}H               H    떾                                                                                                                            J9^a044wJhmii_link_ok  mii_nway_restart  mii_ethtool_gset  mii_ethtool_get_link_ksettings  mii_ethtool_sset  mii_ethtool_set_link_ksettings  mii_check_link  mii_check_media  mii_check_gmii_support  generic_mii_ioctl                                                                                          full half link down
 link up
        link up, %uMbps, %s-duplex, lpa 0x%04X
 license=GPL description=MII hardware support library author=Jeff Garzik <jgarzik@pobox.com> depends= retpoline=Y intree=Y name=mii vermagic=6.1.0-37-amd64 SMP preempt mod_unload modversions                                                                                                                                                                                                                                         (    0  8  0  (                     8                                                                                                                     (    0  8  @  8  0  (                     @                   (    0  8  H  8  0  (                     H                         (  0  (                   0                                                     (    0  8  @  8  0  (                     @        0                                                                                                                                                                                                                                                                                                                                                                                                                                                                               m    __fentry__                                              pHe    __x86_indirect_thunk_rax                                9[    __x86_return_thunk                                      0j    ethtool_convert_legacy_u32_to_link_mode                 U    ethtool_convert_link_mode_to_legacy_u32                 V
    __stack_chk_fail                                        I    netif_carrier_on                                            netif_carrier_off                                       _5    netdev_info                                             zR    module_layout                                                                   mii                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0               A=      h        #       P=        W=    0   _= 
  0   h        %{            @   k=    `   x=      =      =      :"  %     =  
     = [ @        
        %                              Z        Y        X       
   = \ = ] :    =    =    ^       
   = \ =    =    =    `       
    = \ >    b       
   = \ >    d />    d ;>    d       
   = \ : }?  R>    h       
   = \ q>   v>    j       
    = \ : z?  >    l       
    = \ q>   >    n       
*   = \   &   >    p        
9             r    
          
s mii_ioctl_data val_in val_out mii_if_info reg_num_mask full_duplex force_media supports_gmii mdio_read mdio_write mii_if mii_data duplex_chg_out generic_mii_ioctl mii ok_to_print init_media mii_check_media mii_check_link mii_nway_restart mii_link_ok mii_check_gmii_support mii_ethtool_set_link_ksettings ecmd mii_ethtool_sset mii_ethtool_get_link_ksettings mii_ethtool_gset mii_get_an    mii.ko  f#                                                                         
                                            	                      	 $               *     	                A     	                f     	                }     	                     	                     	                     	                     	                     \       	                         &    e              ?    q       	       U    z       	       i           <                                     $           
                     
                     `                   
 
                   
                     l               )    
                D    
 0               a     <               |    
 1                   
 P                    0                   
 Q                   
 b               1     T               L    
 c               u    
                     H                   
                    
                                        
                0    
                L     $               f    
                    
                                        
                    
                                     !            n       ,                   A                   X           )       s    5       '       ;    p                                        =                                             V    `	                                                          p      G                                                0      ?                  H                                                     P      '                           *                     k    p             R                      __crc_mii_link_ok __crc_mii_nway_restart __crc_mii_ethtool_gset __crc_mii_ethtool_get_link_ksettings __crc_mii_ethtool_sset __crc_mii_ethtool_set_link_ksettings __crc_mii_check_link __crc_mii_check_media __crc_mii_check_gmii_support __crc_generic_mii_ioctl __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 __kstrtab_mii_link_ok __kstrtabns_mii_link_ok __ksymtab_mii_link_ok __kstrtab_mii_nway_restart __kstrtabns_mii_nway_restart __ksymtab_mii_nway_restart __kstrtab_mii_ethtool_gset __kstrtabns_mii_ethtool_gset __ksymtab_mii_ethtool_gset __kstrtab_mii_ethtool_get_link_ksettings __kstrtabns_mii_ethtool_get_link_ksettings __ksymtab_mii_ethtool_get_link_ksettings __kstrtab_mii_ethtool_sset __kstrtabns_mii_ethtool_sset __ksymtab_mii_ethtool_sset __kstrtab_mii_ethtool_set_link_ksettings __kstrtabns_mii_ethtool_set_link_ksettings __ksymtab_mii_ethtool_set_link_ksettings __kstrtab_mii_check_link __kstrtabns_mii_check_link __ksymtab_mii_check_link __kstrtab_mii_check_media __kstrtabns_mii_check_media __ksymtab_mii_check_media __kstrtab_mii_check_gmii_support __kstrtabns_mii_check_gmii_support __ksymtab_mii_check_gmii_support __kstrtab_generic_mii_ioctl __kstrtabns_generic_mii_ioctl __ksymtab_generic_mii_ioctl mii_get_an mii_check_media.cold __UNIQUE_ID_license375 __UNIQUE_ID_description374 __UNIQUE_ID_author373 __this_module __fentry__ __x86_indirect_thunk_rax __stack_chk_fail ethtool_convert_link_mode_to_legacy_u32 __x86_return_thunk netif_carrier_off netif_carrier_on ethtool_convert_legacy_u32_to_link_mode netdev_info             >             @   j          G   q          >             @             @            @            @            G   q         >            @            @            G            >            @            @            G            >            @   1         @   9         G   D         G   Q         >            G            @            G            @   \         @            >            @            @            @            @            K            K             K            >   A         @            @            G            @            C            @   =         @            @   	         @   	         @   +	         @   U	         A   a	         >   ~	         <   	         J   	         @   	         @   Q
         G   V
         H   _
            q       y
         @   
                   
            
                   '            G       ,                   1         >   :         <   [         G   a         J   k         H   q         >            @   ]         @            G            @   `
         @   
         @   
         @   
         @   
         @   
         @                                 M                	                           =                     B          M   G             
      R                     _                    |             
                 M                	                                      I                     2                     3                     B                     /                     0                     E                     )                      *           $          ?           (          ,           ,          -           0          =           4                      8          !           <          L           @                     D                     H          D           L          &           P          '           T          :           X          #           \          $           `          <           d                     h                     l          F           p                     t                                                        p                    p                                              (             P      0                   8                   @             `	      H             0      P             p                                                                                                                                                                                      $                   (             0      ,                   0                   4             [      8                   <                   @                   D                   H             @      L                   P                   T                   X             <      \                   `             	      d             	      h             *	      l             	      p             	      t             x
      x                   |             \                                      _
                   
                   
                   
                   
                   
                    i                                                                              8                   C                                                                $             P
      (             Z      ,                                                      n                    p                    w                    y                    {                    }                    ~                            $                   (                   ,                   0                   4                   8                    <                   @             h      D             p      H             v      L                   P                   T                   X                   \                   `                   d                    h                   l             8      p             =      t             C      x             H      |             P                   V                   ]                                                                                                                                     w                                                                                                                                                                                                                                                                                                                $                                                                                                                                                                                                                                                                                                               $            Y	      (            `	      ,            g	      0            i	      4            n	      8            r	      <            u	      @            I
      D            J
      H            L
      L            N
      P            P
      T            U
      X            0      \            6      `            Z      d            _      h            `      l            e      p            j      t            o      x            p      |            w                  y                  {                  }                  ~                                                                                                                                                                                                      4                                              .symtab .strtab .shstrtab .note.gnu.build-id .note.Linux .rela.text .rela.text.unlikely .rela__ksymtab __kcrctab __ksymtab_strings .rela__mcount_loc .rodata.str1.1 .rodata.str1.8 .modinfo .rela.retpoline_sites .rela.return_sites .orc_unwind .rela.orc_unwind_ip __versions .data .gnu.linkonce.this_module .bss .comment .note.GNU-stack .BTF .gnu_debuglink                                                                                           @       $                              .                     d       <                              ?                            4                             :      @               /      h                          J                                                         E      @               X7      8                          ^                     t      x                              Y      @               8                                h                           (                              r      2                                                                             X                                    @               `;                                      2               ;                                         2               `      (                                                                                                           G                                          @               h<                                                           0                                    @               @                                                                                                                                                       @               0A      
                                                                                                                                                                                     @               1                                                         6     0                     P                             ?                                                          O                           a                             T                     4"                                                          @"      P          :                 	                      )      ^                                                   K      c                             0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  m|L!Jzӣe'K齷C: տ<2TL&i"J!DY\Ez :oPl
Ų/pM/doBF
Ogzmc> mxYX%v@o ;^IdJHuZ_FOѣ̒PfZm2A<8@)2cQBr
/E?qJ;I>_]BE?l@(ZB-rK         ~Module signature appended~
 070701000A04DB000081A4000000000000000000000001682F6DA70000950B000000CA0000000200000000000000000000004200000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/net_failover.ko ELF          >                              @     @ 3 2          GNU H0a#1Mae*        Linux                Linux   6.1.0-37-amd64      I1HH<
II)I	I)HI IEH~I
HH   u    ff.         HHQHh  H	  H	  H9uHuHA              ff.     f    H9	  t	H9	  u1                 H9	  t	H9	  u1    1            HG8u    HG8H    f.         AWAVAUATUSL	  HM  I$   1i     I$  H	     HI    E$   E$   HŸ   A   fA9DBL	  MtJI   Li     I  HH	     I    E#   HA   fA9DBH   H  HL   H  HH fD   HA   HDH   []A\A]A^A_    A   A   E1H	     9ff.          ATUHSHL	  H9	  t	I9   HH    HH    HH    H    H   H    Hp  H9p  tLHǃ	      MtA$      A$$  $  Ht
H  eHH    )Hǃ	      Ht
H  eHH    HH    H    1[]A\    D      AUATAUSL	  HMtL    Ņu#H	  HtD    ŅuD   1[]A\A]    Mt   L        SHH	  H	  Hp  H;p  tBH    H    Hx`           u1[    H    t    Ht    ff.     f    ATIUHSH	  HtH]uH	  HtHEtLH[]A\    AD$    fAD$1[]A\        SH~H
   H        H{$[   H        ff.         ATIUSH	  Ht    I$	  Ht    [1]A\    fD      AUATAUHSHL	  MtL    uLH	  Ht>ED    t)Mt&DLD$    D$H[]A\A]    1H[]A\A]        USH    H	  HtHH    HH    H	  HtHH    HH    []    fD      AW   AVAUIATIM   UI$  SI$   H   eH%(   H$   1Lt$LHH    I}LHI$   HH)IE I$  H)΁   IGH    I$	  HthL    I$	  LHHHL$H$H4$I$	  HHI$	  H   I$P
  HL$H)H)΁   HI$	  HtcLM$X
      LLHH$QH4$I$`
  HHI)I$X
  H   L)A   AI$  DH    IE H{LHI$   IGH   H)H)ށ   HH    H$   eH+%(   uH   []A\A]A^A_        ff.     @     UHSH	  HHt1H   H@0HtV    S|fS,  9s$[]    V|ft&BfS,  9r܉)9s[]    111    S|릐    ATIUSH	  HHtHuI$	  Ht&HtC,HkH1fC|[]A\    I$  HteH@H߾       1[]A\    L    Htff.     f    AWAVAUATUHSHH	  HG  1H    AąuvL	  M`  1L    AąuMH *  H1      t!؃H<HH      ;  rE1   H    e       H  E1HH$eD-          t]DHHH  L   L    D   H    H      ǃ   LA    D;  rH<$       H=        HD[]A\A]A^A_    L	  M 1L    AąLE1H@     AT      UHSLp  p      H    HH  H  1HH   Lp  ]  H%H   H
  Hǃ       H   Hǃ      Hǃ   H0         H߉   $  $      Ņ    H    H    H    H= w	[]A\    H߉    H    Hc[]A\    f.         HtYUSHoHH        H	  Ht    H	  Ht    H// -*- C++ -*-

// Copyright (C) 2007-2022 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 parallel/multiway_merge.h
*  @brief Implementation of sequential and parallel multiway merge.
*
*  Explanations on the high-speed merging routines in the appendix of
*
*  P. Sanders.
*  Fast priority queues for cached memory.
*  ACM Journal of Experimental Algorithmics, 5, 2000.
*
*  This file is a GNU parallel extension to the Standard C++ Library.
*/

// Written by Johannes Singler and Manuel Holtgrewe.

#ifndef _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H
#define _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H

#include <vector>

#include <bits/stl_algo.h>
#include <parallel/features.h>
#include <parallel/parallel.h>
#include <parallel/losertree.h>
#include <parallel/multiseq_selection.h>
#if _GLIBCXX_PARALLEL_ASSERTIONS
#include <parallel/checkers.h>
#endif

/** @brief Length of a sequence described by a pair of iterators. */
#define _GLIBCXX_PARALLEL_LENGTH(__s) ((__s).second - (__s).first)

namespace __gnu_parallel
{
  template<typename _RAIter1, typename _RAIter2, typename _OutputIterator,
	   typename _DifferenceTp, typename _Compare>
    _OutputIterator
    __merge_advance(_RAIter1&, _RAIter1, _RAIter2&, _RAIter2,
		    _OutputIterator, _DifferenceTp, _Compare);

  /** @brief _Iterator wrapper supporting an implicit supremum at the end
   *         of the sequence, dominating all comparisons.
   *
   * The implicit supremum comes with a performance cost.
   *
   * Deriving from _RAIter is not possible since
   * _RAIter need not be a class.
   */
  template<typename _RAIter, typename _Compare>
    class _GuardedIterator
    {
    private:
      /** @brief Current iterator __position. */
      _RAIter _M_current;

      /** @brief End iterator of the sequence. */
      _RAIter _M_end;

      /** @brief _Compare. */
      _Compare& __comp;

    public:
      /** @brief Constructor. Sets iterator to beginning of sequence.
      *  @param __begin Begin iterator of sequence.
      *  @param __end End iterator of sequence.
      *  @param __comp Comparator provided for associated overloaded
      *  compare operators. */
      _GuardedIterator(_RAIter __begin, _RAIter __end, _Compare& __comp)
      : _M_current(__begin), _M_end(__end), __comp(__comp)
      { }

      /** @brief Pre-increment operator.
      *  @return This. */
      _GuardedIterator<_RAIter, _Compare>&
      operator++()
      {
	++_M_current;
	return *this;
      }

      /** @brief Dereference operator.
      *  @return Referenced element. */
      typename std::iterator_traits<_RAIter>::value_type&
      operator*() const
      { return *_M_current; }

      /** @brief Convert to wrapped iterator.
      *  @return Wrapped iterator. */
      operator _RAIter() const
      { return _M_current; }

      /** @brief Compare two elements referenced by guarded iterators.
       *  @param __bi1 First iterator.
       *  @param __bi2 Second iterator.
       *  @return @c true if less. */
      friend bool
      operator<(const _GuardedIterator<_RAIter, _Compare>& __bi1,
		const _GuardedIterator<_RAIter, _Compare>& __bi2)
      {
	if (__bi1._M_current == __bi1._M_end)       // __bi1 is sup
	  return __bi2._M_current == __bi2._M_end;  // __bi2 is not sup
	if (__bi2._M_current == __bi2._M_end)       // __bi2 is sup
	  return true;
	return (__bi1.__comp)(*__bi1, *__bi2);      // normal compare
      }

      /** @brief Compare two elements referenced by guarded iterators.
       *  @param __bi1 First iterator.
       *  @param __bi2 Second iterator.
       *  @return @c True if less equal. */
      friend bool
      operator<=(const _GuardedIterator<_RAIter, _Compare>& __bi1,
		 const _GuardedIterator<_RAIter, _Compare>& __bi2)
      {
	if (__bi2._M_current == __bi2._M_end)       // __bi1 is sup
	  return __bi1._M_current != __bi1._M_end;  // __bi2 is not sup
	if (__bi1._M_current == __bi1._M_end)       // __bi2 is sup
	  return false;
	return !(__bi1.__comp)(*__bi2, *__bi1);     // normal compare
      } 
    };

  template<typename _RAIter, typename _Compare>
    class _UnguardedIterator
    {
    private:
      /** @brief Current iterator __position. */
      _RAIter _M_current;
      /** @brief _Compare. */
      _Compare& __comp;

    public:
      /** @brief Constructor. Sets iterator to beginning of sequence.
      *  @param __begin Begin iterator of sequence.
      *  @param __end Unused, only for compatibility.
      *  @param __comp Unused, only for compatibility. */
      _UnguardedIterator(_RAIter __begin,
                	 _RAIter /* __end */, _Compare& __comp)
      : _M_current(__begin), __comp(__comp)
      { }

      /** @brief Pre-increment operator.
      *  @return This. */
      _UnguardedIterator<_RAIter, _Compare>&
      operator++()
      {
	++_M_current;
	return *this;
      }

      /** @brief Dereference operator.
      *  @return Referenced element. */
      typename std::iterator_traits<_RAIter>::value_type&
      operator*() const
      { return *_M_current; }

      /** @brief Convert to wrapped iterator.
      *  @return Wrapped iterator. */
      operator _RAIter() const
      { return _M_current; }

      /** @brief Compare two elements referenced by unguarded iterators.
       *  @param __bi1 First iterator.
       *  @param __bi2 Second iterator.
       *  @return @c true if less. */
      friend bool
      operator<(const _UnguardedIterator<_RAIter, _Compare>& __bi1,
		const _UnguardedIterator<_RAIter, _Compare>& __bi2)
      {
	// Normal compare.
	return (__bi1.__comp)(*__bi1, *__bi2);
      }

      /** @brief Compare two elements referenced by unguarded iterators.
       *  @param __bi1 First iterator.
       *  @param __bi2 Second iterator.
       *  @return @c True if less equal. */
      friend bool
      operator<=(const _UnguardedIterator<_RAIter, _Compare>& __bi1,
		 const _UnguardedIterator<_RAIter, _Compare>& __bi2)
      {
	// Normal compare.
	return !(__bi1.__comp)(*__bi2, *__bi1);
      }
    };

  /** @brief Highly efficient 3-way merging procedure.
   *
   * Merging is done with the algorithm implementation described by Peter
   * Sanders.  Basically, the idea is to minimize the number of necessary
   * comparison after merging an element.  The implementation trick
   * that makes this fast is that the order of the sequences is stored
   * in the instruction pointer (translated into labels in C++).
   *
   * This works well for merging up to 4 sequences.
   *
   * Note that making the merging stable does @a not come at a
   * performance hit.
   *
   * Whether the merging is done guarded or unguarded is selected by the
   * used iterator class.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  template<template<typename _RAI, typename _Cp> class iterator,
           typename _RAIterIterator,
           typename _RAIter3,
           typename _DifferenceTp,
           typename _Compare>
    _RAIter3
    multiway_merge_3_variant(_RAIterIterator __seqs_begin,
			     _RAIterIterator __seqs_end,
			     _RAIter3 __target,
			     _DifferenceTp __length, _Compare __comp)
    {
      _GLIBCXX_CALL(__length);

      typedef _DifferenceTp _DifferenceType;

      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      if (__length == 0)
	return __target;

#if _GLIBCXX_PARALLEL_ASSERTIONS
      _DifferenceTp __orig_length = __length;
#endif

      iterator<_RAIter1, _Compare>
	__seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
	__seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
	__seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp);

      if (__seq0 <= __seq1)
	{
          if (__seq1 <= __seq2)
            goto __s012;
          else
            if (__seq2 <  __seq0)
              goto __s201;
            else
              goto __s021;
	}
      else
	{
          if (__seq1 <= __seq2)
            {
              if (__seq0 <= __seq2)
        	goto __s102;
              else
        	goto __s120;
            }
          else
            goto __s210;
	}
#define _GLIBCXX_PARALLEL_MERGE_3_CASE(__a, __b, __c, __c0, __c1) \
      __s ## __a ## __b ## __c :                            \
	*__target = *__seq ## __a;                          \
	++__target;                                         \
	--__length;                                         \
	++__seq ## __a;                                     \
	if (__length == 0) goto __finish;                   \
	if (__seq ## __a __c0 __seq ## __b) goto __s ## __a ## __b ## __c; \
	if (__seq ## __a __c1 __seq ## __c) goto __s ## __b ## __a ## __c; \
	goto __s ## __b ## __c ## __a;

      _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 1, 2, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 2, 0, <=, < );
      _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 0, 1, < , < );
      _GLIBCXX_PARALLEL_MERGE_3_CASE(1, 0, 2, < , <=);
      _GLIBCXX_PARALLEL_MERGE_3_CASE(0, 2, 1, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_3_CASE(2, 1, 0, < , < );

#undef _GLIBCXX_PARALLEL_MERGE_3_CASE

    __finish:
      ;

#if _GLIBCXX_PARALLEL_ASSERTIONS
    _GLIBCXX_PARALLEL_ASSERT(
	((_RAIter1)__seq0 - __seqs_begin[0].first) +
	((_RAIter1)__seq1 - __seqs_begin[1].first) +
	((_RAIter1)__seq2 - __seqs_begin[2].first)
	== __orig_length);
#endif

      __seqs_begin[0].first = __seq0;
      __seqs_begin[1].first = __seq1;
      __seqs_begin[2].first = __seq2;

      return __target;
    }

  /**
   * @brief Highly efficient 4-way merging procedure.
   *
   * Merging is done with the algorithm implementation described by Peter
   * Sanders. Basically, the idea is to minimize the number of necessary
   * comparison after merging an element.  The implementation trick
   * that makes this fast is that the order of the sequences is stored
   * in the instruction pointer (translated into goto labels in C++).
   *
   * This works well for merging up to 4 sequences.
   *
   * Note that making the merging stable does @a not come at a
   * performance hit.
   *
   * Whether the merging is done guarded or unguarded is selected by the
   * used iterator class.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  template<template<typename _RAI, typename _Cp> class iterator,
           typename _RAIterIterator,
           typename _RAIter3,
           typename _DifferenceTp,
           typename _Compare>
    _RAIter3
    multiway_merge_4_variant(_RAIterIterator __seqs_begin,
                             _RAIterIterator __seqs_end,
                             _RAIter3 __target,
                             _DifferenceTp __length, _Compare __comp)
    {
      _GLIBCXX_CALL(__length);
      typedef _DifferenceTp _DifferenceType;

      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      iterator<_RAIter1, _Compare>
	__seq0(__seqs_begin[0].first, __seqs_begin[0].second, __comp),
	__seq1(__seqs_begin[1].first, __seqs_begin[1].second, __comp),
	__seq2(__seqs_begin[2].first, __seqs_begin[2].second, __comp),
	__seq3(__seqs_begin[3].first, __seqs_begin[3].second, __comp);

#define _GLIBCXX_PARALLEL_DECISION(__a, __b, __c, __d) {  \
	if (__seq ## __d < __seq ## __a)		  \
	  goto __s ## __d ## __a ## __b ## __c;		  \
	if (__seq ## __d < __seq ## __b)		  \
	  goto __s ## __a ## __d ## __b ## __c;		  \
	if (__seq ## __d < __seq ## __c)		  \
	  goto __s ## __a ## __b ## __d ## __c;		  \
	goto __s ## __a ## __b ## __c ## __d;  }

      if (__seq0 <= __seq1)
	{
          if (__seq1 <= __seq2)
            _GLIBCXX_PARALLEL_DECISION(0,1,2,3)
            else
              if (__seq2 < __seq0)
        	_GLIBCXX_PARALLEL_DECISION(2,0,1,3)
        	else
                  _GLIBCXX_PARALLEL_DECISION(0,2,1,3)
                    }
      else
	{
          if (__seq1 <= __seq2)
            {
              if (__seq0 <= __seq2)
        	_GLIBCXX_PARALLEL_DECISION(1,0,2,3)
        	else
                  _GLIBCXX_PARALLEL_DECISION(1,2,0,3)
                    }
          else
            _GLIBCXX_PARALLEL_DECISION(2,1,0,3)
              }

#define _GLIBCXX_PARALLEL_MERGE_4_CASE(__a, __b, __c, __d,  \
				       __c0, __c1, __c2)    \
      __s ## __a ## __b ## __c ## __d:                      \
      if (__length == 0) goto __finish;                     \
      *__target = *__seq ## __a;                            \
      ++__target;                                           \
      --__length;                                           \
      ++__seq ## __a;                                       \
      if (__seq ## __a __c0 __seq ## __b)      \
	goto __s ## __a ## __b ## __c ## __d;  \
      if (__seq ## __a __c1 __seq ## __c)      \
	goto __s ## __b ## __a ## __c ## __d;  \
      if (__seq ## __a __c2 __seq ## __d)      \
	goto __s ## __b ## __c ## __a ## __d;  \
      goto __s ## __b ## __c ## __d ## __a;

      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 2, 3, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 1, 3, 2, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 1, 3, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 2, 3, 1, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 1, 2, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(0, 3, 2, 1, <=, <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 2, 3, < , <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 0, 3, 2, < , <=, <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 0, 3, <=, < , <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 2, 3, 0, <=, <=, < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 0, 2, <=, < , <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(1, 3, 2, 0, <=, <=, < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 1, 3, < , < , <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 0, 3, 1, < , <=, < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 0, 3, < , < , <=);
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 1, 3, 0, < , <=, < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 0, 1, <=, < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(2, 3, 1, 0, <=, < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 1, 2, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 0, 2, 1, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 0, 2, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 1, 2, 0, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 0, 1, < , < , < );
      _GLIBCXX_PARALLEL_MERGE_4_CASE(3, 2, 1, 0, < , < , < );

#undef _GLIBCXX_PARALLEL_MERGE_4_CASE
#undef _GLIBCXX_PARALLEL_DECISION

    __finish:
      ;

      __seqs_begin[0].first = __seq0;
      __seqs_begin[1].first = __seq1;
      __seqs_begin[2].first = __seq2;
      __seqs_begin[3].first = __seq3;

      return __target;
    }

  /** @brief Multi-way merging procedure for a high branching factor,
   *         guarded case.
   *
   * This merging variant uses a LoserTree class as selected by <tt>_LT</tt>.
   *
   * Stability is selected through the used LoserTree class <tt>_LT</tt>.
   *
   * At least one non-empty sequence is required.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  template<typename _LT,
           typename _RAIterIterator,
           typename _RAIter3,
           typename _DifferenceTp,
           typename _Compare>
    _RAIter3
    multiway_merge_loser_tree(_RAIterIterator __seqs_begin,
                              _RAIterIterator __seqs_end,
                              _RAIter3 __target,
                              _DifferenceTp __length, _Compare __comp)
    {
      _GLIBCXX_CALL(__length)

      typedef _DifferenceTp _DifferenceType;
      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);

      _LT __lt(__k, __comp);

      // Default value for potentially non-default-constructible types.
      _ValueType* __arbitrary_element = 0;

      for (_SeqNumber __t = 0; __t < __k; ++__t)
	{
          if(!__arbitrary_element
	     && _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__t]) > 0)
            __arbitrary_element = &(*__seqs_begin[__t].first);
	}

      for (_SeqNumber __t = 0; __t < __k; ++__t)
	{
          if (__seqs_begin[__t].first == __seqs_begin[__t].second)
            __lt.__insert_start(*__arbitrary_element, __t, true);
          else
            __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
	}

      __lt.__init();

      _SeqNumber __source;

      for (_DifferenceType __i = 0; __i < __length; ++__i)
	{
          //take out
          __source = __lt.__get_min_source();

          *(__target++) = *(__seqs_begin[__source].first++);

          // Feed.
          if (__seqs_begin[__source].first == __seqs_begin[__source].second)
            __lt.__delete_min_insert(*__arbitrary_element, true);
          else
            // Replace from same __source.
            __lt.__delete_min_insert(*__seqs_begin[__source].first, false);
	}

      return __target;
    }

  /** @brief Multi-way merging procedure for a high branching factor,
   *         unguarded case.
   *
   * Merging is done using the LoserTree class <tt>_LT</tt>.
   *
   * Stability is selected by the used LoserTrees.
   *
   * @pre No input will run out of elements during the merge.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  template<typename _LT,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp, typename _Compare>
    _RAIter3
    multiway_merge_loser_tree_unguarded(_RAIterIterator __seqs_begin,
					_RAIterIterator __seqs_end,
					_RAIter3 __target,
       const typename std::iterator_traits<typename std::iterator_traits<
	  _RAIterIterator>::value_type::first_type>::value_type&
					__sentinel,
					_DifferenceTp __length,
					_Compare __comp)
    {
      _GLIBCXX_CALL(__length)
      typedef _DifferenceTp _DifferenceType;

      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      _SeqNumber __k = __seqs_end - __seqs_begin;

      _LT __lt(__k, __sentinel, __comp);

      for (_SeqNumber __t = 0; __t < __k; ++__t)
	{
#if _GLIBCXX_PARALLEL_ASSERTIONS
          _GLIBCXX_PARALLEL_ASSERT(__seqs_begin[__t].first
                                   != __seqs_begin[__t].second);
#endif
          __lt.__insert_start(*__seqs_begin[__t].first, __t, false);
	}

      __lt.__init();

      _SeqNumber __source;

#if _GLIBCXX_PARALLEL_ASSERTIONS
      _DifferenceType __i = 0;
#endif

      _RAIter3 __target_end = __target + __length;
      while (__target < __target_end)
	{
          // Take out.
          __source = __lt.__get_min_source();

#if _GLIBCXX_PARALLEL_ASSERTIONS
          _GLIBCXX_PARALLEL_ASSERT(0 <= __source && __source < __k);
          _GLIBCXX_PARALLEL_ASSERT(__i == 0
              || !__comp(*(__seqs_begin[__source].first), *(__target - 1)));
#endif

          // Feed.
          *(__target++) = *(__seqs_begin[__source].first++);

#if _GLIBCXX_PARALLEL_ASSERTIONS
          ++__i;
#endif
          // Replace from same __source.
          __lt.__delete_min_insert(*__seqs_begin[__source].first, false);
	}

      return __target;
    }


  /** @brief Multi-way merging procedure for a high branching factor,
   *         requiring sentinels to exist.
   *
   * @tparam _UnguardedLoserTree Loser Tree variant to use for the unguarded
   *				 merging.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, less equal than the
   * total number of elements available.
   *
   * @return End iterator of output sequence.
   */
  template<typename _UnguardedLoserTree,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIter3
    multiway_merge_loser_tree_sentinel(_RAIterIterator __seqs_begin,
				       _RAIterIterator __seqs_end,
				       _RAIter3 __target,
      const typename std::iterator_traits<typename std::iterator_traits<
	_RAIterIterator>::value_type::first_type>::value_type&
				       __sentinel,
				       _DifferenceTp __length,
				       _Compare __comp)
    {
      _GLIBCXX_CALL(__length)

      typedef _DifferenceTp _DifferenceType;
      typedef std::iterator_traits<_RAIterIterator> _TraitsType;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      _RAIter3 __target_end;

      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
	// Move the sequence ends to the sentinel.  This has the
	// effect that the sentinel appears to be within the sequence. Then,
	// we can use the unguarded variant if we merge out as many
	// non-sentinel elements as we have.
	++((*__s).second);

      __target_end = multiway_merge_loser_tree_unguarded<_UnguardedLoserTree>
	(__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);

#if _GLIBCXX_PARALLEL_ASSERTIONS
      _GLIBCXX_PARALLEL_ASSERT(__target_end == __target + __length);
      _GLIBCXX_PARALLEL_ASSERT(__is_sorted(__target, __target_end, __comp));
#endif

      // Restore the sequence ends so the sentinels are not contained in the
      // sequence any more (see comment in loop above).
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
	--((*__s).second);

      return __target_end;
    }

  /**
   * @brief Traits for determining whether the loser tree should
   *   use pointers or copies.
   *
   * The field "_M_use_pointer" is used to determine whether to use pointers
   * in he loser trees or whether to copy the values into the loser tree.
   *
   * The default behavior is to use pointers if the data type is 4 times as
   * big as the pointer to it.
   *
   * Specialize for your data type to customize the behavior.
   *
   * Example:
   *
   *   template<>
   *   struct _LoserTreeTraits<int>
   *   { static const bool _M_use_pointer = false; };
   *
   *   template<>
   *   struct _LoserTreeTraits<heavyweight_type>
   *   { static const bool _M_use_pointer = true; };
   *
   * @param _Tp type to give the loser tree traits for.
   */
  template <typename _Tp>
    struct _LoserTreeTraits
    {
      /**
       * @brief True iff to use pointers instead of values in loser trees.
       *
       * The default behavior is to use pointers if the data type is four
       * times as big as the pointer to it.
       */
      static const bool _M_use_pointer = (sizeof(_Tp) > 4 * sizeof(_Tp*));
    };

  /**
   * @brief Switch for 3-way merging with __sentinels turned off.
   *
   * Note that 3-way merging is always stable!
   */
  template<bool __sentinels /*default == false*/,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_3_variant_sentinel_switch
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
		 _DifferenceTp __length, _Compare __comp)
      { return multiway_merge_3_variant<_GuardedIterator>
	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
    };

  /**
   * @brief Switch for 3-way merging with __sentinels turned on.
   *
   * Note that 3-way merging is always stable!
   */
  template<typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_3_variant_sentinel_switch<true, _RAIterIterator,
						      _RAIter3, _DifferenceTp,
						      _Compare>
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
		 _DifferenceTp __length, _Compare __comp)
      { return multiway_merge_3_variant<_UnguardedIterator>
	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
    };

  /**
   * @brief Switch for 4-way merging with __sentinels turned off.
   *
   * Note that 4-way merging is always stable!
   */
  template<bool __sentinels /*default == false*/,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_4_variant_sentinel_switch
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
		 _DifferenceTp __length, _Compare __comp)
      { return multiway_merge_4_variant<_GuardedIterator>
	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
    };

  /**
   * @brief Switch for 4-way merging with __sentinels turned on.
   *
   * Note that 4-way merging is always stable!
   */
  template<typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_4_variant_sentinel_switch<true, _RAIterIterator,
						      _RAIter3, _DifferenceTp,
						      _Compare>
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
		 _DifferenceTp __length, _Compare __comp)
      { return multiway_merge_4_variant<_UnguardedIterator>
	  (__seqs_begin, __seqs_end, __target, __length, __comp); }
    };

  /**
   * @brief Switch for k-way merging with __sentinels turned on.
   */
  template<bool __sentinels,
	   bool __stable,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_k_variant_sentinel_switch
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
      const typename std::iterator_traits<typename std::iterator_traits<
      _RAIterIterator>::value_type::first_type>::value_type&
		 __sentinel,
		 _DifferenceTp __length, _Compare __comp)
      {
	typedef typename std::iterator_traits<_RAIterIterator>
	  ::value_type::first_type
	  _RAIter1;
	typedef typename std::iterator_traits<_RAIter1>::value_type
	  _ValueType;

	return multiway_merge_loser_tree_sentinel<
	typename __gnu_cxx::__conditional_type<
	_LoserTreeTraits<_ValueType>::_M_use_pointer,
	  _LoserTreePointerUnguarded<__stable, _ValueType, _Compare>,
	  _LoserTreeUnguarded<__stable, _ValueType, _Compare>
          >::__type>
	  (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
      }
    };

  /**
   * @brief Switch for k-way merging with __sentinels turned off.
   */
  template<bool __stable,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    struct __multiway_merge_k_variant_sentinel_switch<false, __stable,
						      _RAIterIterator,
						      _RAIter3, _DifferenceTp,
						      _Compare>
    {
      _RAIter3
      operator()(_RAIterIterator __seqs_begin,
		 _RAIterIterator __seqs_end,
		 _RAIter3 __target,
       const typename std::iterator_traits<typename std::iterator_traits<
       _RAIterIterator>::value_type::first_type>::value_type&
		 __sentinel,
		 _DifferenceTp __length, _Compare __comp)
      {
	typedef typename std::iterator_traits<_RAIterIterator>
	  ::value_type::first_type
	  _RAIter1;
	typedef typename std::iterator_traits<_RAIter1>::value_type
	  _ValueType;

	return multiway_merge_loser_tree<
	typename __gnu_cxx::__conditional_type<
	_LoserTreeTraits<_ValueType>::_M_use_pointer,
	  _LoserTreePointer<__stable, _ValueType, _Compare>,
	  _LoserTree<__stable, _ValueType, _Compare>
          >::__type >(__seqs_begin, __seqs_end, __target, __length, __comp);
      }
    };

  /** @brief Sequential multi-way merging switch.
   *
   *  The _GLIBCXX_PARALLEL_DECISION is based on the branching factor and
   *  runtime settings.
   *  @param __seqs_begin Begin iterator of iterator pair input sequence.
   *  @param __seqs_end End iterator of iterator pair input sequence.
   *  @param __target Begin iterator of output sequence.
   *  @param __comp Comparator.
   *  @param __length Maximum length to merge, possibly larger than the
   *  number of elements available.
   *  @param __sentinel The sequences have __a __sentinel element.
   *  @return End iterator of output sequence. */
  template<bool __stable,
	   bool __sentinels,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIter3
    __sequential_multiway_merge(_RAIterIterator __seqs_begin,
				_RAIterIterator __seqs_end,
				_RAIter3 __target,
      const typename std::iterator_traits<typename std::iterator_traits<
	_RAIterIterator>::value_type::first_type>::value_type&
				__sentinel,
				_DifferenceTp __length, _Compare __comp)
    {
      _GLIBCXX_CALL(__length)

      typedef _DifferenceTp _DifferenceType;
      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

#if _GLIBCXX_PARALLEL_ASSERTIONS
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
	{
          _GLIBCXX_PARALLEL_ASSERT(__is_sorted((*__s).first,
					       (*__s).second, __comp));
	}
#endif

      _DifferenceTp __total_length = 0;
      for (_RAIterIterator __s = __seqs_begin; __s != __seqs_end; ++__s)
	__total_length += _GLIBCXX_PARALLEL_LENGTH(*__s);

      __length = std::min<_DifferenceTp>(__length, __total_length);

      if(__length == 0)
	return __target;

      _RAIter3 __return_target = __target;
      _SeqNumber __k = static_cast<_SeqNumber>(__seqs_end - __seqs_begin);

      switch (__k)
	{
	case 0:
          break;
	case 1:
          __return_target = std::copy(__seqs_begin[0].first,
				      __seqs_begin[0].first + __length,
				      __target);
          __seqs_begin[0].first += __length;
          break;
	case 2:
          __return_target = __merge_advance(__seqs_begin[0].first,
					    __seqs_begin[0].second,
					    __seqs_begin[1].first,
					    __seqs_begin[1].second,
					    __target, __length, __comp);
          break;
	case 3:
          __return_target = __multiway_merge_3_variant_sentinel_switch
	    <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
	    (__seqs_begin, __seqs_end, __target, __length, __comp);
          break;
	case 4:
          __return_target = __multiway_merge_4_variant_sentinel_switch
	    <__sentinels, _RAIterIterator, _RAIter3, _DifferenceTp, _Compare>()
	    (__seqs_begin, __seqs_end, __target, __length, __comp);
          break;
	default:
	  __return_target = __multiway_merge_k_variant_sentinel_switch
	    <__sentinels, __stable, _RAIterIterator, _RAIter3, _DifferenceTp,
	     _Compare>()
	    (__seqs_begin, __seqs_end, __target, __sentinel, __length, __comp);
	  break;
	}
#if _GLIBCXX_PARALLEL_ASSERTIONS
      _GLIBCXX_PARALLEL_ASSERT(
	__is_sorted(__target, __target + __length, __comp));
#endif

      return __return_target;
    }

  /**
   * @brief Stable sorting functor.
   *
   * Used to reduce code instanciation in multiway_merge_sampling_splitting.
   */
  template<bool __stable, class _RAIter, class _StrictWeakOrdering>
    struct _SamplingSorter
    {
      void
      operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
      { __gnu_sequential::stable_sort(__first, __last, __comp); }
    };

  /**
   * @brief Non-__stable sorting functor.
   *
   * Used to reduce code instantiation in multiway_merge_sampling_splitting.
   */
  template<class _RAIter, class _StrictWeakOrdering>
    struct _SamplingSorter<false, _RAIter, _StrictWeakOrdering>
    {
      void
      operator()(_RAIter __first, _RAIter __last, _StrictWeakOrdering __comp)
      { __gnu_sequential::sort(__first, __last, __comp); }
    };

  /**
   * @brief Sampling based splitting for parallel multiway-merge routine.
   */
  template<bool __stable,
	   typename _RAIterIterator,
	   typename _Compare,
	   typename _DifferenceType>
    void
    multiway_merge_sampling_splitting(_RAIterIterator __seqs_begin,
				      _RAIterIterator __seqs_end,
				      _DifferenceType __length,
				      _DifferenceType __total_length,
				      _Compare __comp,
     std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
    {
      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;
      typedef typename std::iterator_traits<_RAIter1>::value_type
	_ValueType;

      // __k sequences.
      const _SeqNumber __k
	= static_cast<_SeqNumber>(__seqs_end - __seqs_begin);

      const _ThreadIndex __num_threads = omp_get_num_threads();

      const _DifferenceType __num_samples =
	__gnu_parallel::_Settings::get().merge_oversampling * __num_threads;

      _ValueType* __samples = static_cast<_ValueType*>
	(::operator new(sizeof(_ValueType) * __k * __num_samples));
      // Sample.
      for (_SeqNumber __s = 0; __s < __k; ++__s)
	for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
	  {
	    _DifferenceType sample_index = static_cast<_DifferenceType>
	      (_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__s])
	       * (double(__i + 1) / (__num_samples + 1))
	       * (double(__length) / __total_length));
	    new(&(__samples[__s * __num_samples + __i]))
              _ValueType(__seqs_begin[__s].first[sample_index]);
	  }

      // Sort stable or non-stable, depending on value of template parameter
      // "__stable".
      _SamplingSorter<__stable, _ValueType*, _Compare>()
	(__samples, __samples + (__num_samples * __k), __comp);

      for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
	// For each slab / processor.
	for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
	  {
	    // For each sequence.
	    if (__slab > 0)
	      __pieces[__slab][__seq].first = std::upper_bound
		(__seqs_begin[__seq].first, __seqs_begin[__seq].second,
		 __samples[__num_samples * __k * __slab / __num_threads],
		 __comp)
		- __seqs_begin[__seq].first;
	    else
	      // Absolute beginning.
	      __pieces[__slab][__seq].first = 0;
	    if ((__slab + 1) < __num_threads)
	      __pieces[__slab][__seq].second = std::upper_bound
		(__seqs_begin[__seq].first, __seqs_begin[__seq].second,
		 __samples[__num_samples * __k * (__slab + 1) / __num_threads],
		 __comp)
		- __seqs_begin[__seq].first;
	    else
              // Absolute end.
	      __pieces[__slab][__seq].second =
		_GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
	  }

      for (_SeqNumber __s = 0; __s < __k; ++__s)
	for (_DifferenceType __i = 0; __i < __num_samples; ++__i)
	  __samples[__s * __num_samples + __i].~_ValueType();
      ::operator delete(__samples);
    }

  /**
   * @brief Exact splitting for parallel multiway-merge routine.
   *
   * None of the passed sequences may be empty.
   */
  template<bool __stable,
	   typename _RAIterIterator,
	   typename _Compare,
	   typename _DifferenceType>
    void
    multiway_merge_exact_splitting(_RAIterIterator __seqs_begin,
				   _RAIterIterator __seqs_end,
				   _DifferenceType __length,
				   _DifferenceType __total_length,
				   _Compare __comp,
       std::vector<std::pair<_DifferenceType, _DifferenceType> > *__pieces)
    {
      typedef typename std::iterator_traits<_RAIterIterator>
	::difference_type _SeqNumber;
      typedef typename std::iterator_traits<_RAIterIterator>
	::value_type::first_type
	_RAIter1;

      const bool __tight = (__total_length == __length);

      // __k sequences.
      const _SeqNumber __k = __seqs_end - __seqs_begin;

      const _ThreadIndex __num_threads = omp_get_num_threads();

      // (Settings::multiway_merge_splitting
      //  == __gnu_parallel::_Settings::EXACT).
      std::vector<_RAIter1>* __offsets = 
	new std::vector<_RAIter1>[__num_threads];
      std::vector<std::pair<_RAIter1, _RAIter1> > __se(__k);

      copy(__seqs_begin, __seqs_end, __se.begin());

      _DifferenceType* __borders =
	new _DifferenceType[__num_threads + 1];
      __equally_split(__length, __num_threads, __borders);

      for (_ThreadIndex __s = 0; __s < (__num_threads - 1); ++__s)
	{
	  __offsets[__s].resize(__k);
	  multiseq_partition(__se.begin(), __se.end(), __borders[__s + 1],
			     __offsets[__s].begin(), __comp);

	  // Last one also needed and available.
	  if (!__tight)
	    {
	      __offsets[__num_threads - 1].resize(__k);
	      multiseq_partition(__se.begin(), __se.end(),
				 _DifferenceType(__length),
				 __offsets[__num_threads - 1].begin(),
				 __comp);
	    }
	}
      delete[] __borders;

      for (_ThreadIndex __slab = 0; __slab < __num_threads; ++__slab)
	{
	  // For each slab / processor.
	  for (_SeqNumber __seq = 0; __seq < __k; ++__seq)
	    {
	      // For each sequence.
	      if (__slab == 0)
		{
		  // Absolute beginning.
		  __pieces[__slab][__seq].first = 0;
		}
	      else
		__pieces[__slab][__seq].first =
		  __pieces[__slab - 1][__seq].second;
	      if (!__tight || __slab < (__num_threads - 1))
		__pieces[__slab][__seq].second =
		  __offsets[__slab][__seq] - __seqs_begin[__seq].first;
	      else
		{
		  // __slab == __num_threads - 1
		  __pieces[__slab][__seq].second =
                    _GLIBCXX_PARALLEL_LENGTH(__seqs_begin[__seq]);
		}
	    }
	}
      delete[] __offsets;
    }

  /** @brief Parallel multi-way merge routine.
   *
   * The _GLIBCXX_PARALLEL_DECISION is based on the branching factor
   * and runtime settings.
   *
   * Must not be called if the number of sequences is 1.
   *
   * @tparam _Splitter functor to split input (either __exact or sampling based)
   * @tparam __stable Stable merging incurs a performance penalty.
   * @tparam __sentinel Ignored.
   *
   * @param __seqs_begin Begin iterator of iterator pair input sequence.
   * @param __seqs_end End iterator of iterator pair input sequence.
   * @param __target Begin iterator of output sequence.
   * @param __comp Comparator.
   * @param __length Maximum length to merge, possibly larger than the
   * number of elements available.
   * @return End iterator of output sequence.
   */
  template<bool __stable,
	   bool __sentinels,
	   typename _RAIterIterator,
	   typename _RAIter3,
	   typename _DifferenceTp,
	   typename _Splitter,
	   typename _Compare>
    _RAIter3
    parallel_multiway_merge(_RAIterIterator __seqs_begin,
                            _RAIterIterator __seqs_end,
                            _RAIter3 __target,
                            _Splitter __splitter,
                            _DifferenceTp __length,
                            _Compare __comp,
                            _ThreadIndex __num_threads)
      {
#if _GLIBCXX_PARALLEL_ASSERTIONS
	_GLIBCXX_PARALLEL_ASSERT(__seqs_end - __seqs_begin > 1);
#endif

	_GLIBCXX_CALL(__length)

	typedef _DifferenceTp _DifferenceType;
        typedef typename std::iterator_traits<_RAIterIterator>
	  ::difference_type _SeqNumber;
	typedef typename std::iterator_traits<_RAIterIterator>
          ::value_type::first_type
          _RAIter1;
	typedef typename
          std::iterator_traits<_RAIter1>::value_type _ValueType;

	// Leave only non-empty sequences.
	typedef std::pair<_RAIter1, _RAIter1> seq_type;
	seq_type* __ne_seqs = new seq_type[__seqs_end - __seqs_begin];
	_SeqNumber __k = 0;
	_DifferenceType __total_length = 0;
	for (_RAIterIterator __raii = __seqs_begin;
             __raii != __seqs_end; ++__raii)
          {
            _DifferenceTp __seq_length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
            if(__seq_length > 0)
              {
        	__total_length += __seq_length;
        	__ne_seqs[__k++] = *__raii;
              }
          }

	_GLIBCXX_CALL(__total_length)

	__length = std::min<_DifferenceTp>(__length, __total_length);

	if (__total_length == 0 || __k == 0)
	  {
	    delete[] __ne_seqs;
	    return __target;
	  }

	std::vector<std::pair<_DifferenceType, _DifferenceType> >* __pieces;

	__num_threads = static_cast<_ThreadIndex>
          (std::min<_DifferenceType>(__num_threads, __total_length));

#       pragma omp parallel num_threads (__num_threads)
	{
#         pragma omp single
	  {
	    __num_threads = omp_get_num_threads();
	    // Thread __t will have to merge pieces[__iam][0..__k - 1]
	    __pieces = new std::vector<
	    std::pair<_DifferenceType, _DifferenceType> >[__num_threads];
	    for (_ThreadIndex __s = 0; __s < __num_threads; ++__s)
	      __pieces[__s].resize(__k);

	    _DifferenceType __num_samples =
	      __gnu_parallel::_Settings::get().merge_oversampling
	      * __num_threads;

	    __splitter(__ne_seqs, __ne_seqs + __k, __length, __total_length,
		       __comp, __pieces);
	  } //single

	  _ThreadIndex __iam = omp_get_thread_num();

	  _DifferenceType __target_position = 0;

	  for (_SeqNumber __c = 0; __c < __k; ++__c)
	    __target_position += __pieces[__iam][__c].first;

	  seq_type* __chunks = new seq_type[__k];

	  for (_SeqNumber __s = 0; __s < __k; ++__s)
	    __chunks[__s] = std::make_pair(__ne_seqs[__s].first
					   + __pieces[__iam][__s].first,
					   __ne_seqs[__s].first
					   + __pieces[__iam][__s].second);

	  if(__length > __target_position)
	    __sequential_multiway_merge<__stable, __sentinels>
	      (__chunks, __chunks + __k, __target + __target_position,
	       *(__seqs_begin->second), __length - __target_position, __comp);

	  delete[] __chunks;
	} // parallel

#if _GLIBCXX_PARALLEL_ASSERTIONS
	_GLIBCXX_PARALLEL_ASSERT(
          __is_sorted(__target, __target + __length, __comp));
#endif

	__k = 0;
	// Update ends of sequences.
	for (_RAIterIterator __raii = __seqs_begin;
             __raii != __seqs_end; ++__raii)
          {
            _DifferenceTp __length = _GLIBCXX_PARALLEL_LENGTH(*__raii);
            if(__length > 0)
              (*__raii).first += __pieces[__num_threads - 1][__k++].second;
          }

	delete[] __pieces;
	delete[] __ne_seqs;

	return __target + __length;
      }

  /**
   * @brief Multiway Merge Frontend.
   *
   * Merge the sequences specified by seqs_begin and __seqs_end into
   * __target.  __seqs_begin and __seqs_end must point to a sequence of
   * pairs.  These pairs must contain an iterator to the beginning
   * of a sequence in their first entry and an iterator the _M_end of
   * the same sequence in their second entry.
   *
   * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
   * that breaks ties by sequence number but is slower.
   *
   * The first entries of the pairs (i.e. the begin iterators) will be moved
   * forward.
   *
   * The output sequence has to provide enough space for all elements
   * that are written to it.
   *
   * This function will merge the input sequences:
   *
   * - not stable
   * - parallel, depending on the input size and Settings
   * - using sampling for splitting
   * - not using sentinels
   *
   * Example:
   *
   * <pre>
   *   int sequences[10][10];
   *   for (int __i = 0; __i < 10; ++__i)
   *     for (int __j = 0; __i < 10; ++__j)
   *       sequences[__i][__j] = __j;
   *
   *   int __out[33];
   *   std::vector<std::pair<int*> > seqs;
   *   for (int __i = 0; __i < 10; ++__i)
   *     { seqs.push(std::make_pair<int*>(sequences[__i],
   *                                      sequences[__i] + 10)) }
   *
   *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
   * </pre>
   *
   * @see stable_multiway_merge
   *
   * @pre All input sequences must be sorted.
   * @pre Target must provide enough space to merge out length elements or
   *    the number of elements in all sequences, whichever is smaller.
   *
   * @post [__target, return __value) contains merged __elements from the
   *    input sequences.
   * @post return __value - __target = min(__length, number of elements in all
   *    sequences).
   *
   * @tparam _RAIterPairIterator iterator over sequence
   *    of pairs of iterators
   * @tparam _RAIterOut iterator over target sequence
   * @tparam _DifferenceTp difference type for the sequence
   * @tparam _Compare strict weak ordering type to compare elements
   *    in sequences
   *
   * @param __seqs_begin  __begin of sequence __sequence
   * @param __seqs_end    _M_end of sequence __sequence
   * @param __target      target sequence to merge to.
   * @param __comp        strict weak ordering to use for element comparison.
   * @param __length Maximum length to merge, possibly larger than the
   * number of elements available.
   *
   * @return _M_end iterator of output sequence
   */
  // multiway_merge
  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge(_RAIterPairIterator __seqs_begin,
		   _RAIterPairIterator __seqs_end,
		   _RAIterOut __target,
		   _DifferenceTp __length, _Compare __comp,
		   __gnu_parallel::sequential_tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute multiway merge *sequentially*.
      return __sequential_multiway_merge
	</* __stable = */ false, /* __sentinels = */ false>
	(__seqs_begin, __seqs_end, __target,
	 *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge(_RAIterPairIterator __seqs_begin,
		   _RAIterPairIterator __seqs_end,
		   _RAIterOut __target,
		   _DifferenceTp __length, _Compare __comp,
		   __gnu_parallel::exact_tag __tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
	  </* __stable = */ false, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ false,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
	  </* __stable = */ false, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge(_RAIterPairIterator __seqs_begin,
		   _RAIterPairIterator __seqs_end,
		   _RAIterOut __target,
		   _DifferenceTp __length, _Compare __comp,
		   __gnu_parallel::sampling_tag __tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
               __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
	  </* __stable = */ false, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ false,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
	  </* __stable = */ false, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge(_RAIterPairIterator __seqs_begin,
		   _RAIterPairIterator __seqs_end,
		   _RAIterOut __target,
		   _DifferenceTp __length, _Compare __comp,
		   parallel_tag __tag = parallel_tag(0))
    { return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
			    __comp, exact_tag(__tag.__get_num_threads())); }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge(_RAIterPairIterator __seqs_begin,
		   _RAIterPairIterator __seqs_end,
		   _RAIterOut __target,
		   _DifferenceTp __length, _Compare __comp,
		   default_parallel_tag __tag)
    { return multiway_merge(__seqs_begin, __seqs_end, __target, __length,
			    __comp, exact_tag(__tag.__get_num_threads())); }

  // stable_multiway_merge
  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
			  _RAIterPairIterator __seqs_end,
			  _RAIterOut __target,
			  _DifferenceTp __length, _Compare __comp,
			  __gnu_parallel::sequential_tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute multiway merge *sequentially*.
      return __sequential_multiway_merge
	</* __stable = */ true, /* __sentinels = */ false>
          (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
			  _RAIterPairIterator __seqs_end,
			  _RAIterOut __target,
			  _DifferenceTp __length, _Compare __comp,
			  __gnu_parallel::exact_tag __tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ true, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ true,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
	  </* __stable = */ true, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
			  _RAIterPairIterator __seqs_end,
			  _RAIterOut __target,
			  _DifferenceTp __length, _Compare __comp,
			  sampling_tag __tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ true, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_sampling_splitting</* __stable = */ true,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */ true, /* __sentinels = */ false>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
			  _RAIterPairIterator __seqs_end,
			  _RAIterOut __target,
			  _DifferenceTp __length, _Compare __comp,
			  parallel_tag __tag = parallel_tag(0))
    {
      return stable_multiway_merge
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge(_RAIterPairIterator __seqs_begin,
			  _RAIterPairIterator __seqs_end,
			  _RAIterOut __target,
			  _DifferenceTp __length, _Compare __comp,
			  default_parallel_tag __tag)
    {
      return stable_multiway_merge
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  /**
   * @brief Multiway Merge Frontend.
   *
   * Merge the sequences specified by seqs_begin and __seqs_end into
   * __target.  __seqs_begin and __seqs_end must point to a sequence of
   * pairs.  These pairs must contain an iterator to the beginning
   * of a sequence in their first entry and an iterator the _M_end of
   * the same sequence in their second entry.
   *
   * Ties are broken arbitrarily.  See stable_multiway_merge for a variant
   * that breaks ties by sequence number but is slower.
   *
   * The first entries of the pairs (i.e. the begin iterators) will be moved
   * forward accordingly.
   *
   * The output sequence has to provide enough space for all elements
   * that are written to it.
   *
   * This function will merge the input sequences:
   *
   * - not stable
   * - parallel, depending on the input size and Settings
   * - using sampling for splitting
   * - using sentinels
   *
   * You have to take care that the element the _M_end iterator points to is
   * readable and contains a value that is greater than any other non-sentinel
   * value in all sequences.
   *
   * Example:
   *
   * <pre>
   *   int sequences[10][11];
   *   for (int __i = 0; __i < 10; ++__i)
   *     for (int __j = 0; __i < 11; ++__j)
   *       sequences[__i][__j] = __j; // __last one is sentinel!
   *
   *   int __out[33];
   *   std::vector<std::pair<int*> > seqs;
   *   for (int __i = 0; __i < 10; ++__i)
   *     { seqs.push(std::make_pair<int*>(sequences[__i],
   *                                      sequences[__i] + 10)) }
   *
   *   multiway_merge(seqs.begin(), seqs.end(), __target, std::less<int>(), 33);
   * </pre>
   *
   * @pre All input sequences must be sorted.
   * @pre Target must provide enough space to merge out length elements or
   *    the number of elements in all sequences, whichever is smaller.
   * @pre For each @c __i, @c __seqs_begin[__i].second must be the end
   *    marker of the sequence, but also reference the one more __sentinel
   *    element.
   *
   * @post [__target, return __value) contains merged __elements from the
   *    input sequences.
   * @post return __value - __target = min(__length, number of elements in all
   *    sequences).
   *
   * @see stable_multiway_merge_sentinels
   *
   * @tparam _RAIterPairIterator iterator over sequence
   *    of pairs of iterators
   * @tparam _RAIterOut iterator over target sequence
   * @tparam _DifferenceTp difference type for the sequence
   * @tparam _Compare strict weak ordering type to compare elements
   *    in sequences
   *
   * @param __seqs_begin  __begin of sequence __sequence
   * @param __seqs_end    _M_end of sequence __sequence
   * @param __target      target sequence to merge to.
   * @param __comp        strict weak ordering to use for element comparison.
   * @param __length Maximum length to merge, possibly larger than the
   * number of elements available.
   *
   * @return _M_end iterator of output sequence
   */
  // multiway_merge_sentinels
  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
			     _RAIterPairIterator __seqs_end,
			     _RAIterOut __target,
			     _DifferenceTp __length, _Compare __comp,
			     __gnu_parallel::sequential_tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute multiway merge *sequentially*.
      return __sequential_multiway_merge
	</* __stable = */ false, /* __sentinels = */ true>
          (__seqs_begin, __seqs_end,
           __target, *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
			     _RAIterPairIterator __seqs_end,
			     _RAIterOut __target,
			     _DifferenceTp __length, _Compare __comp,
			     __gnu_parallel::exact_tag __tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ false, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ false,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */ false, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
			     _RAIterPairIterator __seqs_end,
			     _RAIterOut __target,
			     _DifferenceTp __length, _Compare __comp,
			     sampling_tag __tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ false, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_sampling_splitting</* __stable = */ false,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */false, /* __sentinels = */ true>(
            __seqs_begin, __seqs_end, __target,
	    *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
			     _RAIterPairIterator __seqs_end,
			     _RAIterOut __target,
			     _DifferenceTp __length, _Compare __comp,
			     parallel_tag __tag = parallel_tag(0))
    {
      return multiway_merge_sentinels
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
			     _RAIterPairIterator __seqs_end,
			     _RAIterOut __target,
			     _DifferenceTp __length, _Compare __comp,
			     default_parallel_tag __tag)
    {
      return multiway_merge_sentinels
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  // stable_multiway_merge_sentinels
  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
				    _RAIterPairIterator __seqs_end,
				    _RAIterOut __target,
				    _DifferenceTp __length, _Compare __comp,
				    __gnu_parallel::sequential_tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute multiway merge *sequentially*.
      return __sequential_multiway_merge
	</* __stable = */ true, /* __sentinels = */ true>
	(__seqs_begin, __seqs_end, __target,
	 *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
				    _RAIterPairIterator __seqs_end,
				    _RAIterOut __target,
				    _DifferenceTp __length, _Compare __comp,
				    __gnu_parallel::exact_tag __tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
            __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
            __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ true, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_exact_splitting</* __stable = */ true,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */ true, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
				    _RAIterPairIterator __seqs_end,
				    _RAIterOut __target,
				    _DifferenceTp __length,
				    _Compare __comp,
				    sampling_tag __tag)
    {
      typedef _DifferenceTp _DifferenceType;
      _GLIBCXX_CALL(__seqs_end - __seqs_begin)

      // catch special case: no sequences
      if (__seqs_begin == __seqs_end)
	return __target;

      // Execute merge; maybe parallel, depending on the number of merged
      // elements and the number of sequences and global thresholds in
      // Settings.
      if ((__seqs_end - __seqs_begin > 1)
	  && _GLIBCXX_PARALLEL_CONDITION(
            ((__seqs_end - __seqs_begin) >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_k)
            && ((_SequenceIndex)__length >=
              __gnu_parallel::_Settings::get().multiway_merge_minimal_n)))
	return parallel_multiway_merge
          </* __stable = */ true, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   multiway_merge_sampling_splitting</* __stable = */ true,
	   typename std::iterator_traits<_RAIterPairIterator>
	   ::value_type*, _Compare, _DifferenceTp>,
	   static_cast<_DifferenceType>(__length), __comp,
	   __tag.__get_num_threads());
      else
	return __sequential_multiway_merge
          </* __stable = */ true, /* __sentinels = */ true>
	  (__seqs_begin, __seqs_end, __target,
	   *(__seqs_begin->second), __length, __comp);
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
				    _RAIterPairIterator __seqs_end,
				    _RAIterOut __target,
				    _DifferenceTp __length,
				    _Compare __comp,
				    parallel_tag __tag = parallel_tag(0))
    {
      return stable_multiway_merge_sentinels
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }

  // public interface
  template<typename _RAIterPairIterator,
	   typename _RAIterOut,
	   typename _DifferenceTp,
	   typename _Compare>
    _RAIterOut
    stable_multiway_merge_sentinels(_RAIterPairIterator __seqs_begin,
				    _RAIterPairIterator __seqs_end,
				    _RAIterOut __target,
				    _DifferenceTp __length, _Compare __comp,
				    default_parallel_tag __tag)
    {
      return stable_multiway_merge_sentinels
	(__seqs_begin, __seqs_end, __target, __length, __comp,
	 exact_tag(__tag.__get_num_threads()));
    }
}; // namespace __gnu_parallel

#endif /* _GLIBCXX_PARALLEL_MULTIWAY_MERGE_H */
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   X                  \                  `                  d                  h                  l                  p                  t                  x                  |                                                                                                                                                                                                s
                  ~
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                                                                                          ]                  ^                  c                   q                  r                  w                                                                                                             Y      $            ]      (            _      ,            a      0            f      4            o      8                    <            ;       @            \       D                   H                  L            R      P            s      T                  X                  \                    `                   d                   h                   l                   p                   t                   x                  |                                                                                                                                                                                                      !                                                                                                                                    `                                        `                                                                                                                         `                                                                          `      (                   0                  8                  @            `      `                   h         c           x                                                                c                                                         c                                                                   (         c           8            p      @            0      `                  h         c           x                              P                                 c                                                           &               c                       P                                      /      (         c           8                  @            	      `            8      h         c           x                              
                                                                                                                                  i                      p           8         p           P         i            .symtab .strtab .shstrtab .note.gnu.build-id .note.Linux .rela.text .rela.text.unlikely .rela.init.text .rela.exit.text .rodata.str1.1 .rodata.str1.8 .rela__mcount_loc .rela.rodata .modinfo .rela__param .rela.return_sites .orc_unwind .rela.orc_unwind_ip __versions .rela__bug_table .rela.data .rela.exit.data .rela.init.data .rela.gnu.linkonce.this_module .bss .comment .note.GNU-stack .BTF .gnu_debuglink                                                                                       @       $                              .                     d       <                              ?                            o                             :      @               \      x      )                    J                                                        E      @               hu             )                    ^                                                        Y      @               h{      @      )                    n                                                         i      @                     P      )   	                 y      2               V      @                                  2                                                                                                                @                     @      )   
                                            @                                    @               8            )                                                                                                 X      P                                    @               0             )                                               t                                    @                           )                                                                                                 "                                         @                     h      )                                         &                                                         2                                    
     @                     `       )                                         2                                         @               p      (      )                    +                    7                                    &     @                            )                    ;                    7                                    6     @                            )                     K                    7                    @               F     @               ȥ      0       )   "                 e                    @;                                     j     0               @;      P                             s                     ;                                                          ;      z
                                                  F                                                           F      
      *   a                 	                      S      	                                                                                      0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  u
Y>~Qm
qCŊվe8?hO5eKȧ0.%sIq[Rk3ReIzzÇ;߰&<&⤛#J@`I)O%c,Fy,H|_=t ejr&51$ŒJ@OC~8i<^郚8nW=L!B1U|c#Z\;M;"         ~Module signature appended~
 070701000A04D7000081A4000000000000000000000001682F6DA7000032DB000000CA0000000200000000000000000000003B00000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/nlmon.ko    ELF          >                    '          @     @ & %          GNU h6
f#	jM        Linux                Linux   6.1.0-37-amd64                 8  H      f(  HǇ       HǇ      Ƈ  HǇ   a  Ǉ      Ǉ     Ǉ          f         HGH    f.         SHHeH%(   HD$1HT$HH$    HD$        H$HC    HC    HHD$HCHD$eH+%(   u
H[        fD      H  WpeH    HPH     1    fD      Hǀ	      ff.     @     H	  Hǀ	  HG            H      ff.     @     U  H   S       HHt65    1HcH        5    9r1H  []        H        H                                                                                        alias=rtnl-link-nlmon description=Netlink monitoring device author=Mathieu Geli <geli@enseirb.fr> author=Daniel Borkmann <dborkman@redhat.com> license=GPL v2 depends= retpoline=Y intree=Y name=nlmon vermagic=6.1.0-37-amd64 SMP preempt mod_unload modversions  nlmon                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      (            (                                                                                                                                                                                                                      m    __fentry__                                              9[    __x86_return_thunk                                      \    rtnl_link_register                                      %    dev_lstats_read                                         V
    __stack_chk_fail                                        VS    this_cpu_off                                            #WK    consume_skb                                             Ld    netlink_remove_tap                                      E    netlink_add_tap                                         !N    free_percpu                                             ƥy    rtnl_link_unregister                                    h6y    __alloc_percpu_gfp                                      }    nr_cpu_ids                                              u?h    __cpu_possible_mask                                     S    _find_next_bit                                          zR    module_layout                                                                                                                                                                                                                                                                                                                                   nlmon                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0                         
9             X              
Y A=       i	 3K            [ G=       X=    p         
   P %
    %
   s	  g=    _ v=    j  =    z  =    j  =    j  =    j  =    j  =    s  nlmon nlmon_unregister nlmon_register nlmon_validate nlmon_setup nlmon_get_stats64 nlmon_close nlmon_open nlmon_dev_uninit nlmon_dev_init nlmon_xmit    nlmon.ko    Is                                                                                                                     
                                                   	                           %                   >            	       T                   h            <                                       $                                       g           
                   
       0                                                                             z                  *       
    P                 p              $                 5                   F          c       U                   j           &           <       &           b       -                                                                                    -                     9                  G                     T                     g                     w                                                                                                                                                                                                                                   #                      __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 always_on nlmon_setup nlmon_ops nlmon_ethtool_ops nlmon_validate nlmon_register nlmon_link_ops nlmon_get_stats64 nlmon_xmit nlmon_close nlmon_open nlmon_dev_uninit nlmon_unregister nlmon_dev_init __UNIQUE_ID_alias381 __UNIQUE_ID_description380 __UNIQUE_ID_author379 __UNIQUE_ID_author378 __UNIQUE_ID_license377 __UNIQUE_ID___addressable_cleanup_module376 __UNIQUE_ID___addressable_init_module375 dev_lstats_read consume_skb __this_module this_cpu_off rtnl_link_register netlink_add_tap cleanup_module __fentry__ init_module __stack_chk_fail __alloc_percpu_gfp rtnl_link_unregister _find_next_bit __cpu_possible_mask __x86_return_thunk nr_cpu_ids free_percpu netlink_remove_tap             +             2             +   3                     >                   s          2             +             2             +             $            2            -   !         +   3         '   ?         %   F         2   Q         +   ]         5   q         +            &                    )            +            4            +            .            3            1                    0            3            2             +                        
          (                                  /                                                                                                           (                    0             P      8             p      @                   H                                                                       p                   P                                                                                 
                    r                                                           E                                                                                                    w                                                                                                            $                   (                   ,                   0                   4                    8             J      <             P      @             a      D             p      H                   L                   P                   T                   X                   \                   `                   d                   h                     l                    p                     t                               *                      ,                                (                    @                    8         ,           P         *            .symtab .strtab .shstrtab .note.gnu.build-id .note.Linux .rela.text .rela.init.text .rela.exit.text .rela__mcount_loc .modinfo .rodata.str1.1 .rela.rodata .rela.return_sites .orc_unwind .rela.orc_unwind_ip __versions .rela.exit.data .rela.init.data .rela.data..read_mostly .rela.gnu.linkonce.this_module .bss .comment .note.GNU-stack .BTF .gnu_debuglink                                                                                           @       $                              .                     d       <                              ?                                                         :      @               H            #                    J                                                         E      @                      H       #                    Z                                                         U      @               `       0       #                    j                           P                              e      @                             #   	                 w                                                               2               #                                                        @                                          @               !             #   
                                      0	                                          @               ("             #                                         H	                                                         	      x                                    @               "            #                                         
                                                                                                                                                              @               %             #                                                                                   @               %             #                                                                                    @               %      H       #                                                            @                    @                &      0       #                    1                                                          6     0                      P                             ?                     P                                     O                     P                                   T                                                                                            $   $                 	                            6                                                   0&      c                             0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  +wC2_+AA'@-x"VYOyӯ
"{Mc(fٙH5bt:514BvsU{-O&`lc%&BfBQU;^ ޒ{M+Wp("L!2I:xQYpxt21( ;B?ɕ1FT>h'"lAV@/ka c?Gog
N~_i6 6m         ~Module signature appended~
 070701000A048E000041ED000000000000000000000002688C084800000000000000CA0000000200000000000000000000003600000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/pcs 070701000A048F000081A4000000000000000000000001682F6DA7000087D3000000CA0000000200000000000000000000004200000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/pcs/pcs_xpcs.ko ELF          >                    |          @     @ & %          GNU M	9Y0С{C        Linux                Linux   6.1.0-37-amd64      ATAUHSHӺ@(  H         A%`@A̟DDHE (  H      xNHE @(  H      x/[DHE ]A\(  H  ʺ@    []A\    ff.     @     E1HGHHLɋA~1LAHcAwH9AI I   u    fD          fD      UHSHH]t1Hc]tu   1HE  @(  H      :  H]D  1Hc΋]  u    1Hc΋]tu@1Hc]t	u@πHE  @(  H  H       H3]   1Hcы]   
u  1Hc]tuHE  @(  H      xBHE   @(  H      x#HU [](  H    @    []    1   m1   v     SHGH  @(  H      y[    HS[(  H    @        USHtY  tt[]          A  @  HC  @(  H      t    	    	  d  @       HC @(  H          HSȋ(  H   @        HC  @(  H          HS%  	苲(  H    @        HC @(  H          HSȋ(  H   @             '  @   1
md  t_	  tWd
Ⱥ  @ADHC(  H              y    o@   뮽    ^    D      ATUSHtx  @w]H   ꋰ(  H      x=A   2       Hꋰ(  H      x%   tAuθ[]A\      @    AT    U
  SHH=        Hj  H(   @IH          @I$(  H         	؍Pw9H    1ҋq!;1txHuHL    H[]A\    I$ @(  H      x( @I$(  H      x	uvHcHH    HJIT$H   HcQ~MHAH	HH9t:;(uHNID$    LLAD$quH[]A\    H H9uHcH    HGHHH   HcQ~$HAH	HH9t;0uHtA    H H9u˸    ff.     f    HHR HeH%(   HL$1H@H$    HD$    HHL   Hcq~lHAH4	HH9tY;uHt%HHc ]t1H$HHcHc]u]   HH    HD$eH+%(   u1H    H L9u    f.         AWAVAUIATIUSHGHXH   HcSz  HCH
HH9c  ;0uHc  C    p  S  I$  @(  H      AŅ   t,I$D  @  (  H         I$@(  H      xI$%  (  H  @    xVI$ @(  H      x7I$H  (    %   @    x~  []A\A]A^A_    F  I$  @(  H      AƅxI$H  (  A   tD  @      xI$(  H  @    rI$%  (  H  @    HL       A  I$E   @(  H      AI$1ɺ@(  H      x  EtK   H H9m[]A\A]A^A_    []A\A]A^A_    IE @   HCHu[L]A\A]A^A_    I$ @(  H      ?I$%  (  H   @    I$  @(  H      I$%  @(  H    @    @HL(E1 @    I$D  @(  H      RIE @|I$D  @(  H      Pff.          H։ff.         AWAVAUATIUHSHHGV HXH   HcK~IHCH	HH9t6;uHtCtA(     H[]A\A]A^A_    H H9uH[]A\A]A^A_    e4@E$HE(   ID$(  H          t¹  td   
   EʀM4M$E(]ID$ @Ml$(  H          HE4	к @E4ID$(  H      z  h  ID$ @(  H      N  {  I|$E4    (  H  @      `
  ID$  @(  H         u
E4    ID$! @(  H      Aƅ   U4A        H      HE(E   '  DE$E4 @E4ID$(  H      Åx	    XHcH    []A\A]A^A_    E4    sL,    e4u 1ɺ   L    O    I|$E4|    ID$ @(  H      x`   U4U4ID$ @(  H        HH[]A\A]A^A_    M4ID$ @(  H         H]  H+ID$ @(  H         tH+ID$ @(  H      xb tH+@tH+tH+ID$ @(  H      x'tH+
tH+]   HHH    HEHUHMH<
  怺	  E   '  HME   EE$H      HE(mID$ @(  H      HL,AA   H      >I    +AwLHHuHLuJH      HuKDqIc־]   H    H\&~ڸ@  A9DL̸ P  D}$a  H3E4        ff.     @     H	H  (     @             H	H  (     @    D      AU?EATẢ   Uպn  SH    K   P  8     H    ,    :     H    
    ;     H         @     H       1ɺ7     H           e     H߁         Df     H߃    xp   E     H    xUA     H    x?%  A     H
      xB  A;   H    1҅O[]A\A]                                 S   m     H    xH߹      [A*!     [    ff.         S}   m     H    xH߹   }   [A*s     [    [HcH    ]H        [HcH    ]H        [HcH    ]H        [H    ]H        H    H        @       I|$H            YHc[H    ]A\A]A^A_    H        I|$    I|$H            H    D$    D$    I|$H            ZHc[H    ]A\A]A^A_    I|$H                                                                                                է	J
bʑ--
Hw뾫    xpcs_link_up_1000basex          xpcs_link_up_sgmii              xpcs_config_usxgmii                                                                             Ζy                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       
            /   ]           
         )   ]               
                            ]                           
             !               "   #   (   4   5   6   7   8   $   %   &   '   9   :   ;   <   =   ]       
         ]   
                     ]   xpcs_get_an_mode  xpcs_get_interfaces  xpcs_config_eee  xpcs_do_config  xpcs_link_up  xpcs_create  xpcs_destroy                                                                                                                                                                 3%s: XPCS access returned %pe
 3%s: xpcs_write returned %pe
  3%s: half duplex not supported
        Link fault condition detected!
 FIFO fault condition detected!
 3xpcs_get_state_c73 returned %pe
      3xpcs_get_state_c37_sgmii returned %pe
        3xpcs_get_state_c37_1000basex returned %pe
 3%s: speed = %d
 Receiver fault detected!
 Transmitter fault detected!
 Link is not locked!
 Link has errors!
        license=GPL v2 depends=libphy,phylink retpoline=Y intree=Y name=pcs_xpcs vermagic=6.1.0-37-amd64 SMP preempt mod_unload modversions                                                                                                                                                                                                                                                                                                                                        (    0  8  0  (                     8  0  (                     8  0  (                     8  0  (                           8                                   (    0  8  @  8  0  (                     @  8  0  (                     @  8  0  (                     @  8  0  (                     @                                                              @  8  0  (                     @  8  0  (                     @                       (                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          z    kfree                                                   W    __bitmap_and                                            m    __fentry__                                              pHe    __x86_indirect_thunk_rax                                ~    _printk                                                 V
    __stack_chk_fail                                        ;    mdiobus_read                                            
    mdiobus_modify_changed                                  S    _find_next_bit                                          fo    _dev_warn                                               9[    __x86_return_thunk                                      G]    phylink_mii_c22_pcs_encode_advertisement                XV    mdiobus_write                                           :    phylink_mii_c22_pcs_decode_state                        wX    kmalloc_trace                                               msleep                                                  -    kmalloc_caches                                          zR    module_layout                                                                   pcs_xpcs                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0         0  0           
=j           A=     P=    ]=    j=    ~=    =     =    =    =    =    =    =    =    =    =     = 0   > @   >    >    ">    ->    8>    D>    P>    \>     h>  @  t>    >    >    >    > 
  8   %{ 
       1{ 
      J =j     \y       by    @  T    `  y      \v      >     >            
Z        Z >      )  b     	  K   @          ]        [ >   (   > d     > f @   ? h    ? j    "? l           
`        a       
       ^            _        c       
        ^     \        e       
       ^            =j            K          g       
        ^        i       
        ^            =j                       k .?       6? _      x   p @   >? ]    B?      x   *         *        ~ @          
n        o                            
q            X              
s            X              
u          J?     Z?    h?    w?    ?    ?    ?    ?       _\ }      J z @   ?       ?       ? }           
x        X       
       |        m        {        y            y              
            o              
       
    ? | ?           
| 6? _  J =j  ?           
    >? ^ @           
    >? ^ "     J =j  \y    by    @           
    >? ^   \ (@           
   >? ^ "     J =j  %{   7@ K   K@           
   ? | J =j  "     %{   W@           
   ? | f@    5    v@           
    ? | ݽ    @           
   >? ^ _\      _ @           
   ? |  ~ @           
   ? | :"     S *     &   @           
   ? | :"     S *   @           
   ? | J =j  @           
   ? | @     A     !A            
9                           
 MLO_PAUSE_NONE MLO_PAUSE_RX MLO_PAUSE_TX MLO_PAUSE_TXRX_MASK MLO_PAUSE_AN MLO_AN_PHY MLO_AN_FIXED MLO_AN_INBAND MAC_SYM_PAUSE MAC_ASYM_PAUSE MAC_10HD MAC_10FD MAC_10 MAC_100HD MAC_100FD MAC_100 MAC_1000HD MAC_1000FD MAC_1000 MAC_2500FD MAC_5000FD MAC_10000FD MAC_20000FD MAC_25000FD MAC_40000FD MAC_50000FD MAC_56000FD MAC_100000FD MAC_200000FD MAC_400000FD phylink_link_state an_enabled an_complete phylink_pcs phylink_pcs_ops pcs_validate pcs_get_state pcs_config pcs_an_restart pcs_link_up dw_xpcs mdiodev pcs xpcs_id DW_XPCS_USXGMII DW_XPCS_10GKR DW_XPCS_XLGMII DW_XPCS_SGMII DW_XPCS_1000BASEX DW_XPCS_2500BASEX DW_XPCS_INTERFACE_MAX xpcs_compat num_interfaces an_mode pma_config xpcs xpcs_destroy xpcs_create xpcs_an_restart xpcs_link_up xpcs_get_state permit_pause_to_mac xpcs_config xpcs_do_config mult_fact_100ns xpcs_config_eee xpcs_get_interfaces xpcs_validate xpcs_config_aneg_c73 xpcs_write xpcs_read xpcs_get_an_mode nxp_sja1110_2500basex_pma_config nxp_sja1110_sgmii_pma_config nxp_sja1105_sgmii_pma_config    pcs_xpcs.ko zDMZ                                                                         
                                                                  	                     	                2     	                 H     	                ]     	                p     	                     	                                                           &                   2       	            ;                   I       <                                     $       %                     @                    ]     0               x                         &                    <                    '                    7               
                     $     8               =     G               X     $               q     H                    U                    H                    V                    b                                        c                    p               ,                    C    0            X          P       h            |       z   
                   
 @                 
                                    
        0          
 `       (                            @
                 `
                |              
                   $   
 `             9   
              Q   
               i   
       (       }   
 ,                
 @                
                  
 @                 
 8                
 0                
 4                
       l       2   
 0             I   
 `             a   
 (             {                          +                                                                       p      (           @      ;                                                                                                                       E       6           
                  J       )                     6                     M                     \                     b          R      f                     y                     g          S                                      E                                                `                                                       $                      __crc_xpcs_get_an_mode __crc_xpcs_get_interfaces __crc_xpcs_config_eee __crc_xpcs_do_config __crc_xpcs_link_up __crc_xpcs_create __crc_xpcs_destroy __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 __kstrtab_xpcs_get_an_mode __kstrtabns_xpcs_get_an_mode __ksymtab_xpcs_get_an_mode __kstrtab_xpcs_get_interfaces __kstrtabns_xpcs_get_interfaces __ksymtab_xpcs_get_interfaces __kstrtab_xpcs_config_eee __kstrtabns_xpcs_config_eee __ksymtab_xpcs_config_eee __kstrtab_xpcs_do_config __kstrtabns_xpcs_do_config __ksymtab_xpcs_do_config __kstrtab_xpcs_link_up __kstrtabns_xpcs_link_up __ksymtab_xpcs_link_up __kstrtab_xpcs_create __kstrtabns_xpcs_create __ksymtab_xpcs_create __kstrtab_xpcs_destroy __kstrtabns_xpcs_destroy __ksymtab_xpcs_destroy xpcs_config_aneg_c73 xpcs_an_restart xpcs_link_up.cold __func__.0 __func__.2 __func__.1 xpcs_soft_reset.isra.0 xpcs_id_list xpcs_phylink_ops xpcs_validate xpcs_config xpcs_get_state xpcs_get_state.cold __UNIQUE_ID_license322 synopsys_xpcs_compat nxp_sja1105_xpcs_compat nxp_sja1110_xpcs_compat xpcs_sgmii_features xpcs_sgmii_interfaces xpcs_2500basex_features xpcs_2500basex_interfaces xpcs_usxgmii_features xpcs_usxgmii_interfaces xpcs_10gkr_features xpcs_10gkr_interfaces xpcs_xlgmii_features xpcs_xlgmii_interfaces xpcs_1000basex_features xpcs_1000basex_interfaces nxp_sja1110_pma_config.part.0 xpcs_write __this_module kfree __bitmap_and xpcs_read __fentry__ __x86_indirect_thunk_rax _printk __stack_chk_fail nxp_sja1110_sgmii_pma_config mdiobus_read mdiobus_modify_changed _find_next_bit _dev_warn __x86_return_thunk phylink_mii_c22_pcs_encode_advertisement mdiobus_write nxp_sja1110_2500basex_pma_config phylink_mii_c22_pcs_decode_state nxp_sja1105_sgmii_pma_config kmalloc_trace msleep kmalloc_caches                N   '          V   b          ^             V             ^             [             N            [   !         N   &         J   1         N   ~         ^   
         ^   z         ^            V            ^            [            N            V            [   <         ^   A         N   e         [   q            D                ^                        V                               ^                      7         V   ?                   f         ^   n                            V                               ^                      @         ^   M            ,       w            [                N            ^            d            V            [            N   +         e   $       0         c   V         V   ~         V                               J            [            V            V   (                   i            `                [            N            [            [            N            K            [            Q            N   q	         V   	         ^   	         V   	         ^   
         V   ?
         ^   Z
         [   ~
         V   
         ^   
         V   
         ^            \   ?         W   h         ^            [            [            O            V   1         ^   T         V            ^            ^            ^   !
         ^   A
         N   a
         N   
         [   
         [   #         V   +                           V            V            V                      &         V   R         V   h            x                V            V   ,                   ;         P   E                   X                   n         Z   {                                               V            V            `   8         V   m         V            V            V             K   t         V            X   O                   ]                  q         N            V            N            ^            N            H            H   4         H   S         H   r         H            H            H            H            H            L   (         H   B         H   T         [   a         N   u         H            N            H            [            N            H            [                                                       P                @       '                     ,          P   7                     ?                     D          P   N                     V                     [          P   b                     i             @       n          P   x                                I                 Y                h                                    P                ,                 Y                                                    Y                E                                    Y                {                   h                 Y               E                                  P   )            ^       .         Y   3            E                 R                                                               a                     $                     %                     T                     '                      (           $          Z           (                     ,                     0          ]           4                     8                     <          U           @                     D                     H          M           L          !           P          "           `                   h             `
      p             @
      x                             M                        `                                             @                  H            ,      X         S                       @                                  _                                          ,               b           `            @      h            8                  0                  4                                    0                                    ,                  `                  (                   @                                                                                                    0                          (             @      0                   8                   @                   H                   P                   X             @
      `             `
      h             p      p                   x                                `                                                                                                                                                                               d                                                                                   $                   (                   ,             Y
      0                   4                   8             
      <             
      @             S      D                   H                                                                                                                                                                                                          $                    (                    ,                    0                    4                   8                    <             *      @             0      D             6      H             :      L                   P                   T                   X                   \                   `                   d                   h                   l                   p                   t                   x             &      |             F                   G                   c                   d                   i                   {                                                                                                                                                        	                                                                            %                                                                                                                                                                                                                                                                                                                                                                                                                                              P
                   Q
      $            S
      (            U
      ,            W
      0            Y
      4            ^
      8                  <                  @                  D                  H                  L                  P                  T                  X                  \                  `                  d                  h                  l                  p                  t                  x                  |                                                                                                      2
                  @
                  T
                  `
                  g
                  i
                  k
                  m
                  q
                  u
                  y
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  
                  &                   1                  2                  4                  6                  8                  :                  ?                                           $                  (                  ,                  0                  4                  8                  <            a      @            p      D                  H                  L                  P                    T                   X                   \                   `                   d            $       h            0       l            1       p            <       t            H       x            I       |            S                   _                   |                                                                                                                                                                                                                                                                                                         !                  7                                                                                                            N                  O                  Q                  S                  X                  `                  y                                                                                                                                                                                            $                  (                   .symtab .strtab .shstrtab .note.gnu.build-id .note.Linux .rela.text .rela.text.unlikely .rela__ksymtab_gpl __kcrctab_gpl .rela.rodata __ksymtab_strings .rela__mcount_loc .rodata.str1.8 .rodata.str1.1 .rela.smp_locks .modinfo .rela.retpoline_sites .rela.return_sites .orc_unwind .rela.orc_unwind_ip __versions .data .gnu.linkonce.this_module .bss .comment .note.GNU-stack .BTF .gnu_debuglink                                                                                      @       $                              .                     d       <                              ?                                                         :      @               M      (      #                    J                           7                             E      @                \            #                    ^                           T                              Y      @               _            #                    l                     @                                                         `      `                              z      @               a            #   
                       2                     q                                                  1                                          @               @d            #   
                       2                     -                                  2                     p                                                  p                                          @               f             #                                         t                                                                                                   @                f             #                                               L                                    @               8f            #                                        I                                                        %      ,                                  @                h            #                    +                    @(                                    6                    ,                                     <                    ,                    @               V                    @0                                     [     0               @0      x                             d                     0                                     t                     0      E                             y                      =                                                          =      	      $   H                 	                      F      3                                                   {                                   0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  (V=Jw'#cuyci#;.*XR>ѝJ;Iؽjd%RŘxB<ɕ,҉cRLFvwGew`JS	u	3RxALص4*d"<&Lstk0u7NcB+k'Yo7JgvE {*d3Ba#ښUx1u_(l)8ZዉjG)1         ~Module signature appended~
 070701000A037C000041ED000000000000000000000003688C084400000000000000CA0000000200000000000000000000003600000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/phy 070701000A0394000081A4000000000000000000000001682F6DA70000253B000000CA0000000200000000000000000000003D00000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/phy/amd.ko  ELF          >                              @     @ # "          GNU j{b$aUm        Linux                Linux   6.1.0-37-amd64      1    @     SH(     H      xu1[    H       [    H    1ې    SH(     H  xU1ɺ       t[    (  H         xߋ(  H         1[O           x(  H         x(        H  [        H       H           H                                        AM79C874 license=GPL author=Heiko Schocher <hs@denx.de> description=AMD PHY driver alias=mdio:0000000000100010010101100001???? depends=libphy retpoline=Y intree=Y name=amd vermagic=6.1.0-37-amd64 SMP preempt mod_unload modversions                                                                                                                                                                                                                  m    __fentry__                                              9[    __x86_return_thunk                                      ![Ha    phy_drivers_register                                    ;    mdiobus_read                                            D    phy_trigger_machine                                         phy_error                                   // -*- C++ -*-
//===-- algorithm_fwd.h --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _PSTL_ALGORITHM_FWD_H
#define _PSTL_ALGORITHM_FWD_H

#include <type_traits>
#include <utility>

namespace __pstl
{
namespace __internal
{

//------------------------------------------------------------------------
// any_of
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Pred>
bool
__brick_any_of(const _ForwardIterator, const _ForwardIterator, _Pred,
               /*__is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _Pred>
bool
__brick_any_of(const _ForwardIterator, const _ForwardIterator, _Pred,
               /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Pred, class _IsVector>
bool
__pattern_any_of(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred, _IsVector,
                 /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Pred, class _IsVector>
bool
__pattern_any_of(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Pred, _IsVector,
                 /*parallel=*/std::true_type);

//------------------------------------------------------------------------
// walk1 (pseudo)
//
// walk1 evaluates f(x) for each dereferenced value x drawn from [first,last)
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Function>
void __brick_walk1(_ForwardIterator, _ForwardIterator, _Function,
                   /*vector=*/std::false_type) noexcept;

template <class _RandomAccessIterator, class _Function>
void __brick_walk1(_RandomAccessIterator, _RandomAccessIterator, _Function,
                   /*vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Function, class _IsVector>
void
__pattern_walk1(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function, _IsVector,
                /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Function, class _IsVector>
void
__pattern_walk1(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Function, _IsVector,
                /*parallel=*/std::true_type);

template <class _ExecutionPolicy, class _ForwardIterator, class _Brick>
void
__pattern_walk_brick(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick,
                     /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Brick>
void
__pattern_walk_brick(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Brick,
                     /*parallel=*/std::true_type);

//------------------------------------------------------------------------
// walk1_n
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Size, class _Function>
_ForwardIterator __brick_walk1_n(_ForwardIterator, _Size, _Function,
                                 /*_IsVectorTag=*/std::false_type);

template <class _RandomAccessIterator, class _DifferenceType, class _Function>
_RandomAccessIterator __brick_walk1_n(_RandomAccessIterator, _DifferenceType, _Function,
                                      /*vectorTag=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function, class _IsVector>
_ForwardIterator
__pattern_walk1_n(_ExecutionPolicy&&, _ForwardIterator, _Size, _Function, _IsVector,
                  /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Function, class _IsVector>
_RandomAccessIterator
__pattern_walk1_n(_ExecutionPolicy&&, _RandomAccessIterator, _Size, _Function, _IsVector,
                  /*is_parallel=*/std::true_type);

template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Brick>
_ForwardIterator
__pattern_walk_brick_n(_ExecutionPolicy&&, _ForwardIterator, _Size, _Brick,
                       /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Brick>
_RandomAccessIterator
__pattern_walk_brick_n(_ExecutionPolicy&&, _RandomAccessIterator, _Size, _Brick,
                       /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// walk2 (pseudo)
//
// walk2 evaluates f(x,y) for deferenced values (x,y) drawn from [first1,last1) and [first2,...)
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _Function>
_ForwardIterator2 __brick_walk2(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function,
                                /*vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _Function>
_ForwardIterator2 __brick_walk2(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function,
                                /*vector=*/std::true_type) noexcept;

template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function>
_ForwardIterator2 __brick_walk2_n(_ForwardIterator1, _Size, _ForwardIterator2, _Function,
                                  /*vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function>
_ForwardIterator2 __brick_walk2_n(_ForwardIterator1, _Size, _ForwardIterator2, _Function,
                                  /*vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function, class _IsVector>
_ForwardIterator2
__pattern_walk2(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, _IsVector,
                /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function, class _IsVector>
_ForwardIterator2
__pattern_walk2(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Function, _IsVector,
                /*parallel=*/std::true_type);

template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function,
          class _IsVector>
_ForwardIterator2
__pattern_walk2_n(_ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Function, _IsVector,
                  /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2,
          class _Function, class _IsVector>
_RandomAccessIterator2
__pattern_walk2_n(_ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Function, _IsVector,
                  /*parallel=*/std::true_type);

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Brick>
_ForwardIterator2
__pattern_walk2_brick(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _Brick,
                      /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _Brick>
_RandomAccessIterator2
__pattern_walk2_brick(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
                      _Brick,
                      /*parallel=*/std::true_type);

template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Brick>
_ForwardIterator2
__pattern_walk2_brick_n(_ExecutionPolicy&&, _ForwardIterator1, _Size, _ForwardIterator2, _Brick,
                        /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2, class _Brick>
_RandomAccessIterator2
__pattern_walk2_brick_n(_ExecutionPolicy&&, _RandomAccessIterator1, _Size, _RandomAccessIterator2, _Brick,
                        /*parallel=*/std::true_type);

//------------------------------------------------------------------------
// walk3 (pseudo)
//
// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3, class _Function>
_ForwardIterator3 __brick_walk3(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator3, _Function,
                                /*vector=*/std::false_type) noexcept;

template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Function>
_RandomAccessIterator3 __brick_walk3(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
                                     _RandomAccessIterator3, _Function,
                                     /*vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3,
          class _Function, class _IsVector>
_ForwardIterator3
__pattern_walk3(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator3,
                _Function, _IsVector,
                /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
          class _RandomAccessIterator3, class _Function, class _IsVector>
_RandomAccessIterator3
__pattern_walk3(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
                _RandomAccessIterator3, _Function, _IsVector, /*parallel=*/std::true_type);

//------------------------------------------------------------------------
// equal
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
bool __brick_equal(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate,
                   /* is_vector = */ std::false_type) noexcept;

template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
bool __brick_equal(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _BinaryPredicate,
                   /* is_vector = */ std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
bool
__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _BinaryPredicate,
                _IsVector, /* is_parallel = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate,
          class _IsVector>
bool
__pattern_equal(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
                _BinaryPredicate, _IsVector, /* is_parallel = */ std::true_type);

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
bool __brick_equal(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2, _BinaryPredicate,
                   /* is_vector = */ std::false_type) noexcept;

template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
bool __brick_equal(_RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2, _RandomAccessIterator2,
                   _BinaryPredicate, /* is_vector = */ std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
bool
__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                _BinaryPredicate, _IsVector, /* is_parallel = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate,
          class _IsVector>
bool
__pattern_equal(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
                _RandomAccessIterator2, _BinaryPredicate, _IsVector, /* is_parallel = */ std::true_type);

//------------------------------------------------------------------------
// find_if
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Predicate>
_ForwardIterator __brick_find_if(_ForwardIterator, _ForwardIterator, _Predicate,
                                 /*is_vector=*/std::false_type) noexcept;

template <class _RandomAccessIterator, class _Predicate>
_RandomAccessIterator __brick_find_if(_RandomAccessIterator, _RandomAccessIterator, _Predicate,
                                      /*is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate, class _IsVector>
_ForwardIterator
__pattern_find_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate, _IsVector,
                  /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate, class _IsVector>
_ForwardIterator
__pattern_find_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate, _IsVector,
                  /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// find_end
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1 __brick_find_end(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                   _BinaryPredicate,
                                   /*__is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1 __brick_find_end(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                   _BinaryPredicate,
                                   /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_find_end(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                   _BinaryPredicate, _IsVector,
                   /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_find_end(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                   _BinaryPredicate, _IsVector,
                   /*is_parallel=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// find_first_of
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1 __brick_find_first_of(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                        _BinaryPredicate,
                                        /*__is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1 __brick_find_first_of(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                        _BinaryPredicate,
                                        /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_find_first_of(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                        _BinaryPredicate, _IsVector, /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_find_first_of(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                        _BinaryPredicate, _IsVector, /*is_parallel=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// search
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1 __brick_search(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                 _BinaryPredicate,
                                 /*vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1 __brick_search(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                 _BinaryPredicate,
                                 /*vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_search(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                 _BinaryPredicate, _IsVector,
                 /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_search(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                 _BinaryPredicate, _IsVector,
                 /*is_parallel=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// search_n
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
_ForwardIterator
__brick_search_n(_ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate,
                 /*vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
_ForwardIterator
__brick_search_n(_ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate,
                 /*vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate,
          class IsVector>
_ForwardIterator
__pattern_search_n(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Size, const _Tp&, _BinaryPredicate,
                   IsVector,
                   /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate,
          class IsVector>
_RandomAccessIterator
__pattern_search_n(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Size, const _Tp&,
                   _BinaryPredicate, IsVector,
                   /*is_parallel=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// copy_n
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Size, class _OutputIterator>
_OutputIterator __brick_copy_n(_ForwardIterator, _Size, _OutputIterator,
                               /*vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _Size, class _OutputIterator>
_OutputIterator __brick_copy_n(_ForwardIterator, _Size, _OutputIterator,
                               /*vector=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// copy
//------------------------------------------------------------------------

template <class _ForwardIterator, class _OutputIterator>
_OutputIterator __brick_copy(_ForwardIterator, _ForwardIterator, _OutputIterator,
                             /*vector=*/std::false_type) noexcept;

template <class _RandomAccessIterator, class _OutputIterator>
_OutputIterator __brick_copy(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
                             /*vector=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// move
//------------------------------------------------------------------------

template <class _ForwardIterator, class _OutputIterator>
_OutputIterator __brick_move(_ForwardIterator, _ForwardIterator, _OutputIterator,
                             /*vector=*/std::false_type) noexcept;

template <class _RandomAccessIterator, class _OutputIterator>
_OutputIterator __brick_move(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
                             /*vector=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// swap_ranges
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
                    /*vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
                    /*vector=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// copy_if
//------------------------------------------------------------------------

template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
_OutputIterator __brick_copy_if(_ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate,
                                /*vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
_OutputIterator __brick_copy_if(_ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate,
                                /*vector=*/std::true_type) noexcept;

template <class _DifferenceType, class _ForwardIterator, class _UnaryPredicate>
std::pair<_DifferenceType, _DifferenceType>
__brick_calc_mask_1(_ForwardIterator, _ForwardIterator, bool* __restrict, _UnaryPredicate,
                    /*vector=*/std::false_type) noexcept;
template <class _DifferenceType, class _RandomAccessIterator, class _UnaryPredicate>
std::pair<_DifferenceType, _DifferenceType>
__brick_calc_mask_1(_RandomAccessIterator, _RandomAccessIterator, bool* __restrict, _UnaryPredicate,
                    /*vector=*/std::true_type) noexcept;

template <class _ForwardIterator, class _OutputIterator>
void
__brick_copy_by_mask(_ForwardIterator, _ForwardIterator, _OutputIterator, bool*,
                     /*vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _OutputIterator>
void
__brick_copy_by_mask(_ForwardIterator, _ForwardIterator, _OutputIterator, bool* __restrict,
                     /*vector=*/std::true_type) noexcept;

template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2>
void
__brick_partition_by_mask(_ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, bool*,
                          /*vector=*/std::false_type) noexcept;

template <class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2>
void
__brick_partition_by_mask(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator1, _OutputIterator2, bool*,
                          /*vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryPredicate, class _IsVector>
_OutputIterator
__pattern_copy_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _UnaryPredicate, _IsVector,
                  /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryPredicate,
          class _IsVector>
_OutputIterator
__pattern_copy_if(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _UnaryPredicate,
                  _IsVector, /*parallel=*/std::true_type);

//------------------------------------------------------------------------
// count
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Predicate>
typename std::iterator_traits<_ForwardIterator>::difference_type
    __brick_count(_ForwardIterator, _ForwardIterator, _Predicate,
                  /* is_vector = */ std::true_type) noexcept;

template <class _ForwardIterator, class _Predicate>
typename std::iterator_traits<_ForwardIterator>::difference_type
    __brick_count(_ForwardIterator, _ForwardIterator, _Predicate,
                  /* is_vector = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate, class _IsVector>
typename std::iterator_traits<_ForwardIterator>::difference_type
__pattern_count(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate,
                /* is_parallel */ std::false_type, _IsVector) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate, class _IsVector>
typename std::iterator_traits<_ForwardIterator>::difference_type
__pattern_count(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Predicate,
                /* is_parallel */ std::true_type, _IsVector);

//------------------------------------------------------------------------
// unique
//------------------------------------------------------------------------

template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator __brick_unique(_ForwardIterator, _ForwardIterator, _BinaryPredicate,
                                /*is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator __brick_unique(_ForwardIterator, _ForwardIterator, _BinaryPredicate,
                                /*is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate, class _IsVector>
_ForwardIterator
__pattern_unique(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, _IsVector,
                 /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate, class _IsVector>
_ForwardIterator
__pattern_unique(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate, _IsVector,
                 /*is_parallel=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// unique_copy
//------------------------------------------------------------------------

template <class _ForwardIterator, class OutputIterator, class _BinaryPredicate>
OutputIterator __brick_unique_copy(_ForwardIterator, _ForwardIterator, OutputIterator, _BinaryPredicate,
                                   /*vector=*/std::false_type) noexcept;

template <class _RandomAccessIterator, class _OutputIterator, class _BinaryPredicate>
_OutputIterator __brick_unique_copy(_RandomAccessIterator, _RandomAccessIterator, _OutputIterator, _BinaryPredicate,
                                    /*vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryPredicate,
          class _IsVector>
_OutputIterator
__pattern_unique_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator, _BinaryPredicate,
                      _IsVector, /*parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
_DifferenceType
__brick_calc_mask_2(_RandomAccessIterator, _RandomAccessIterator, bool* __restrict, _BinaryPredicate,
                    /*vector=*/std::false_type) noexcept;

template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
_DifferenceType
__brick_calc_mask_2(_RandomAccessIterator, _RandomAccessIterator, bool* __restrict, _BinaryPredicate,
                    /*vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _BinaryPredicate,
          class _IsVector>
_OutputIterator
__pattern_unique_copy(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator,
                      _BinaryPredicate, _IsVector, /*parallel=*/std::true_type);

//------------------------------------------------------------------------
// reverse
//------------------------------------------------------------------------

template <class _BidirectionalIterator>
void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator,
                     /*__is_vector=*/std::false_type) noexcept;

template <class _BidirectionalIterator>
void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator,
                     /*__is_vector=*/std::true_type) noexcept;

template <class _BidirectionalIterator>
void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator,
                     /*is_vector=*/std::false_type) noexcept;

template <class _BidirectionalIterator>
void __brick_reverse(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator,
                     /*is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _BidirectionalIterator, class _IsVector>
void
__pattern_reverse(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _IsVector,
                  /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _BidirectionalIterator, class _IsVector>
void
__pattern_reverse(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _IsVector,
                  /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// reverse_copy
//------------------------------------------------------------------------

template <class _BidirectionalIterator, class _OutputIterator>
_OutputIterator __brick_reverse_copy(_BidirectionalIterator, _BidirectionalIterator, _OutputIterator,
                                     /*is_vector=*/std::false_type) noexcept;

template <class _BidirectionalIterator, class _OutputIterator>
_OutputIterator __brick_reverse_copy(_BidirectionalIterator, _BidirectionalIterator, _OutputIterator,
                                     /*is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator, class _IsVector>
_OutputIterator
__pattern_reverse_copy(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator, _IsVector,
                       /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator, class _IsVector>
_OutputIterator
__pattern_reverse_copy(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _OutputIterator, _IsVector,
                       /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// rotate
//------------------------------------------------------------------------

template <class _ForwardIterator>
_ForwardIterator __brick_rotate(_ForwardIterator, _ForwardIterator, _ForwardIterator,
                                /*is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator>
_ForwardIterator __brick_rotate(_ForwardIterator, _ForwardIterator, _ForwardIterator,
                                /*is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _IsVector>
_ForwardIterator
__pattern_rotate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _IsVector,
                 /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _IsVector>
_ForwardIterator
__pattern_rotate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _IsVector,
                 /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// rotate_copy
//------------------------------------------------------------------------

template <class _ForwardIterator, class _OutputIterator>
_OutputIterator __brick_rotate_copy(_ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator,
                                    /*__is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _OutputIterator>
_OutputIterator __brick_rotate_copy(_ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator,
                                    /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _IsVector>
_OutputIterator
__pattern_rotate_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator,
                      _IsVector,
                      /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _IsVector>
_OutputIterator
__pattern_rotate_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _ForwardIterator, _OutputIterator,
                      _IsVector,
                      /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// is_partitioned
//------------------------------------------------------------------------

template <class _ForwardIterator, class _UnaryPredicate>
bool __brick_is_partitioned(_ForwardIterator, _ForwardIterator, _UnaryPredicate,
                            /*is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _UnaryPredicate>
bool __brick_is_partitioned(_ForwardIterator, _ForwardIterator, _UnaryPredicate,
                            /*is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
bool
__pattern_is_partitioned(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector,
                         /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
bool
__pattern_is_partitioned(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector,
                         /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// partition
//------------------------------------------------------------------------

template <class _ForwardIterator, class _UnaryPredicate>
_ForwardIterator __brick_partition(_ForwardIterator, _ForwardIterator, _UnaryPredicate,
                                   /*is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _UnaryPredicate>
_ForwardIterator __brick_partition(_ForwardIterator, _ForwardIterator, _UnaryPredicate,
                                   /*is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
_ForwardIterator
__pattern_partition(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector,
                    /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
_ForwardIterator
__pattern_partition(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector,
                    /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// stable_partition
//------------------------------------------------------------------------

template <class _BidirectionalIterator, class _UnaryPredicate>
_BidirectionalIterator __brick_stable_partition(_BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate,
                                                /*__is_vector=*/std::false_type) noexcept;

template <class _BidirectionalIterator, class _UnaryPredicate>
_BidirectionalIterator __brick_stable_partition(_BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate,
                                                /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate, class _IsVector>
_BidirectionalIterator
__pattern_stable_partition(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate,
                           _IsVector,
                           /*is_parallelization=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate, class _IsVector>
_BidirectionalIterator
__pattern_stable_partition(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _UnaryPredicate,
                           _IsVector,
                           /*is_parallelization=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// partition_copy
//------------------------------------------------------------------------

template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
std::pair<_OutputIterator1, _OutputIterator2>
    __brick_partition_copy(_ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, _UnaryPredicate,
                           /*is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
std::pair<_OutputIterator1, _OutputIterator2>
    __brick_partition_copy(_ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2, _UnaryPredicate,
                           /*is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator1, class _OutputIterator2,
          class _UnaryPredicate, class _IsVector>
std::pair<_OutputIterator1, _OutputIterator2>
__pattern_partition_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _OutputIterator1, _OutputIterator2,
                         _UnaryPredicate, _IsVector,
                         /*is_parallelization=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2,
          class _UnaryPredicate, class _IsVector>
std::pair<_OutputIterator1, _OutputIterator2>
__pattern_partition_copy(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _OutputIterator1,
                         _OutputIterator2, _UnaryPredicate, _IsVector,
                         /*is_parallelization=*/std::true_type);

//------------------------------------------------------------------------
// sort
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector,
          class _IsMoveConstructible>
void
__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector /*is_vector*/,
               /*is_parallel=*/std::false_type, _IsMoveConstructible) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector /*is_vector*/,
               /*is_parallel=*/std::true_type,
               /*is_move_constructible=*/std::true_type);

//------------------------------------------------------------------------
// stable_sort
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare,
                      _IsVector /*is_vector*/,
                      /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare,
                      _IsVector /*is_vector*/,
                      /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// partial_sort
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator,
                       _Compare, _IsVector,
                       /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator,
                       _Compare, _IsVector,
                       /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// partial_sort_copy
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare, class _IsVector>
_RandomAccessIterator
__pattern_partial_sort_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _RandomAccessIterator,
                            _RandomAccessIterator, _Compare, _IsVector,
                            /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare, class _IsVector>
_RandomAccessIterator
__pattern_partial_sort_copy(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _RandomAccessIterator,
                            _RandomAccessIterator, _Compare, _IsVector,
                            /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// adjacent_find
//------------------------------------------------------------------------

template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator
__brick_adjacent_find(_ForwardIterator, _ForwardIterator, _BinaryPredicate,
                      /* IsVector = */ std::true_type, bool) noexcept;

template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator
__brick_adjacent_find(_ForwardIterator, _ForwardIterator, _BinaryPredicate,
                      /* IsVector = */ std::false_type, bool) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate, class _IsVector>
_ForwardIterator
__pattern_adjacent_find(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _BinaryPredicate,
                        /* is_parallel */ std::false_type, _IsVector, bool) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate, class _IsVector>
_RandomAccessIterator
__pattern_adjacent_find(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _BinaryPredicate,
                        /* is_parallel */ std::true_type, _IsVector, bool);

//------------------------------------------------------------------------
// nth_element
//------------------------------------------------------------------------
template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare,
                      _IsVector,
                      /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _RandomAccessIterator, _Compare,
                      _IsVector,
                      /*is_parallel=*/std::true_type) noexcept;

//------------------------------------------------------------------------
// fill, fill_n
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Tp>
void
__brick_fill(_ForwardIterator, _ForwardIterator, const _Tp&,
             /* __is_vector = */ std::true_type) noexcept;

template <class _ForwardIterator, class _Tp>
void
__brick_fill(_ForwardIterator, _ForwardIterator, const _Tp&,
             /* __is_vector = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _IsVector>
void
__pattern_fill(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&,
               /*is_parallel=*/std::false_type, _IsVector) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _IsVector>
_ForwardIterator
__pattern_fill(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, const _Tp&,
               /*is_parallel=*/std::true_type, _IsVector);

template <class _OutputIterator, class _Size, class _Tp>
_OutputIterator
__brick_fill_n(_OutputIterator, _Size, const _Tp&,
               /* __is_vector = */ std::true_type) noexcept;

template <class _OutputIterator, class _Size, class _Tp>
_OutputIterator
__brick_fill_n(_OutputIterator, _Size, const _Tp&,
               /* __is_vector = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _OutputIterator, class _Size, class _Tp, class _IsVector>
_OutputIterator
__pattern_fill_n(_ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&,
                 /*is_parallel=*/std::false_type, _IsVector) noexcept;

template <class _ExecutionPolicy, class _OutputIterator, class _Size, class _Tp, class _IsVector>
_OutputIterator
__pattern_fill_n(_ExecutionPolicy&&, _OutputIterator, _Size, const _Tp&,
                 /*is_parallel=*/std::true_type, _IsVector);

//------------------------------------------------------------------------
// generate, generate_n
//------------------------------------------------------------------------

template <class _RandomAccessIterator, class _Generator>
void __brick_generate(_RandomAccessIterator, _RandomAccessIterator, _Generator,
                      /* is_vector = */ std::true_type) noexcept;

template <class _ForwardIterator, class _Generator>
void __brick_generate(_ForwardIterator, _ForwardIterator, _Generator,
                      /* is_vector = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Generator, class _IsVector>
void
__pattern_generate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator,
                   /*is_parallel=*/std::false_type, _IsVector) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _Generator, class _IsVector>
_ForwardIterator
__pattern_generate(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Generator,
                   /*is_parallel=*/std::true_type, _IsVector);

template <class OutputIterator, class Size, class _Generator>
OutputIterator __brick_generate_n(OutputIterator, Size, _Generator,
                                  /* is_vector = */ std::true_type) noexcept;

template <class OutputIterator, class Size, class _Generator>
OutputIterator __brick_generate_n(OutputIterator, Size, _Generator,
                                  /* is_vector = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class OutputIterator, class Size, class _Generator, class _IsVector>
OutputIterator
__pattern_generate_n(_ExecutionPolicy&&, OutputIterator, Size, _Generator,
                     /*is_parallel=*/std::false_type, _IsVector) noexcept;

template <class _ExecutionPolicy, class OutputIterator, class Size, class _Generator, class _IsVector>
OutputIterator
__pattern_generate_n(_ExecutionPolicy&&, OutputIterator, Size, _Generator,
                     /*is_parallel=*/std::true_type, _IsVector);

//------------------------------------------------------------------------
// remove
//------------------------------------------------------------------------
template <class _ForwardIterator, class _UnaryPredicate>
_ForwardIterator __brick_remove_if(_ForwardIterator, _ForwardIterator, _UnaryPredicate,
                                   /* __is_vector = */ std::false_type) noexcept;

template <class _RandomAccessIterator, class _UnaryPredicate>
_RandomAccessIterator __brick_remove_if(_RandomAccessIterator, _RandomAccessIterator, _UnaryPredicate,
                                        /* __is_vector = */ std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
_ForwardIterator
__pattern_remove_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector,
                    /*is_parallel*/ std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
_ForwardIterator
__pattern_remove_if(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _UnaryPredicate, _IsVector,
                    /*is_parallel*/ std::true_type) noexcept;

//------------------------------------------------------------------------
// merge
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_merge(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                              _OutputIterator, _Compare,
                              /* __is_vector = */ std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_merge(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                              _OutputIterator, _Compare,
                              /* __is_vector = */ std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_merge(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                _OutputIterator, _Compare, _IsVector, /* is_parallel = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_merge(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
                _RandomAccessIterator2, _OutputIterator, _Compare, _IsVector,
                /* is_parallel = */ std::true_type);

//------------------------------------------------------------------------
// inplace_merge
//------------------------------------------------------------------------

template <class _BidirectionalIterator, class _Compare>
void __brick_inplace_merge(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, _Compare,
                           /* __is_vector = */ std::false_type) noexcept;

template <class _BidirectionalIterator, class _Compare>
void __brick_inplace_merge(_BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator, _Compare,
                           /* __is_vector = */ std::true_type) noexcept;

template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare, class _IsVector>
void
__pattern_inplace_merge(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator,
                        _Compare, _IsVector,
                        /* is_parallel = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare, class _IsVector>
void
__pattern_inplace_merge(_ExecutionPolicy&&, _BidirectionalIterator, _BidirectionalIterator, _BidirectionalIterator,
                        _Compare, _IsVector,
                        /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                   _Compare, _IsVector,
                   /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                   _Compare, _IsVector,
                   /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// set_union
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_set_union(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                  _OutputIterator, _Compare,
                                  /*__is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_set_union(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                  _OutputIterator, _Compare,
                                  /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_union(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                    _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_union(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                    _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// set_intersection
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_set_intersection(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                         _OutputIterator, _Compare,
                                         /*__is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_set_intersection(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                         _OutputIterator, _Compare,
                                         /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_intersection(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2,
                           _ForwardIterator2, _OutputIterator, _Compare, _IsVector,
                           /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_intersection(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2,
                           _ForwardIterator2, _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// set_difference
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_set_difference(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                       _OutputIterator, _Compare,
                                       /*__is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_set_difference(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                       _OutputIterator, _Compare,
                                       /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                         _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                         _OutputIterator, _Compare, _IsVector, /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// set_symmetric_difference
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_set_symmetric_difference(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2,
                                                 _ForwardIterator2, _OutputIterator, _Compare,
                                                 /*__is_vector=*/std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator __brick_set_symmetric_difference(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2,
                                                 _ForwardIterator2, _OutputIterator, _Compare,
                                                 /*__is_vector=*/std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_symmetric_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2,
                                   _ForwardIterator2, _OutputIterator, _Compare, _IsVector,
                                   /*is_parallel=*/std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_symmetric_difference(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2,
                                   _ForwardIterator2, _OutputIterator, _Compare, _IsVector,
                                   /*is_parallel=*/std::true_type);

//------------------------------------------------------------------------
// is_heap_until
//------------------------------------------------------------------------

template <class _RandomAccessIterator, class _Compare>
_RandomAccessIterator __brick_is_heap_until(_RandomAccessIterator, _RandomAccessIterator, _Compare,
                                            /* __is_vector = */ std::false_type) noexcept;

template <class _RandomAccessIterator, class _Compare>
_RandomAccessIterator __brick_is_heap_until(_RandomAccessIterator, _RandomAccessIterator, _Compare,
                                            /* __is_vector = */ std::true_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
_RandomAccessIterator
__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector,
                        /* is_parallel = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
_RandomAccessIterator
__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector,
                        /* is_parallel = */ std::true_type) noexcept;

//------------------------------------------------------------------------
// min_element
//------------------------------------------------------------------------

template <typename _ForwardIterator, typename _Compare>
_ForwardIterator __brick_min_element(_ForwardIterator, _ForwardIterator, _Compare,
                                     /* __is_vector = */ std::false_type) noexcept;

template <typename _ForwardIterator, typename _Compare>
_ForwardIterator __brick_min_element(_ForwardIterator, _ForwardIterator, _Compare,
                                     /* __is_vector = */ std::true_type) noexcept;

template <typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare, typename _IsVector>
_ForwardIterator
__pattern_min_element(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare, _IsVector,
                      /* is_parallel = */ std::false_type) noexcept;

template <typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _IsVector>
_RandomAccessIterator
__pattern_min_element(_ExecutionPolicy&&, _RandomAccessIterator, _RandomAccessIterator, _Compare, _IsVector,
                      /* is_parallel = */ std::true_type);

//------------------------------------------------------------------------
// minmax_element
//------------------------------------------------------------------------

template <typename _ForwardIterator, typename _Compare>
std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(_ForwardIterator, _ForwardIterator, _Compare,
                                                                     /* __is_vector = */ std::false_type) noexcept;

template <typename _ForwardIterator, typename _Compare>
std::pair<_ForwardIterator, _ForwardIterator> __brick_minmax_element(_ForwardIterator, _ForwardIterator, _Compare,
                                                                     /* __is_vector = */ std::true_type) noexcept;

template <typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare, typename _IsVector>
std::pair<_ForwardIterator, _ForwardIterator>
__pattern_minmax_element(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare, _IsVector,
                         /* is_parallel = */ std::false_type) noexcept;

template <typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare, typename _IsVector>
std::pair<_ForwardIterator, _ForwardIterator>
__pattern_minmax_element(_ExecutionPolicy&&, _ForwardIterator, _ForwardIterator, _Compare, _IsVector,
                         /* is_parallel = */ std::true_type);

//------------------------------------------------------------------------
// mismatch
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(_ForwardIterator1, _ForwardIterator1,
                                                                 _ForwardIterator2, _ForwardIterator2, _Predicate,
                                                                 /* __is_vector = */ std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
std::pair<_ForwardIterator1, _ForwardIterator2> __brick_mismatch(_ForwardIterator1, _ForwardIterator1,
                                                                 _ForwardIterator2, _ForwardIterator2, _Predicate,
                                                                 /* __is_vector = */ std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate, class _IsVector>
std::pair<_ForwardIterator1, _ForwardIterator2>
__pattern_mismatch(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                   _Predicate, _IsVector,
                   /* is_parallel = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _Predicate,
          class _IsVector>
std::pair<_RandomAccessIterator1, _RandomAccessIterator2>
__pattern_mismatch(_ExecutionPolicy&&, _RandomAccessIterator1, _RandomAccessIterator1, _RandomAccessIterator2,
                   _RandomAccessIterator2, _Predicate, _IsVector, /* is_parallel = */ std::true_type) noexcept;

//------------------------------------------------------------------------
// lexicographical_compare
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _Compare>
bool __brick_lexicographical_compare(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                     _Compare,
                                     /* __is_vector = */ std::false_type) noexcept;

template <class _ForwardIterator1, class _ForwardIterator2, class _Compare>
bool __brick_lexicographical_compare(_ForwardIterator1, _ForwardIterator1, _ForwardIterator2, _ForwardIterator2,
                                     _Compare,
                                     /* __is_vector = */ std::true_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_lexicographical_compare(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2,
                                  _ForwardIterator2, _Compare, _IsVector, /* is_parallel = */ std::false_type) noexcept;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_lexicographical_compare(_ExecutionPolicy&&, _ForwardIterator1, _ForwardIterator1, _ForwardIterator2,
                                  _ForwardIterator2, _Compare, _IsVector, /* is_parallel = */ std::true_type) noexcept;

} // namespace __internal
} // namespace __pstl
#endif /* _PSTL_ALGORITHM_FWD_H */
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            08x_cable_test_start qca808x_soft_reset qca808x_read_status qca808x_config_init qca808x_phy_ms_random_seed_set qca83xx_suspend qca83xx_resume qca83xx_link_change_notify qca83xx_config_init at803x_cable_test_start at803x_cable_test_get_status at803x_cdt_wait_for_completion tuna at803x_set_tunable at803x_get_tunable at803x_config_aneg at803x_read_status at803x_read_specific_status at803x_link_change_notify at803x_handle_interrupt at803x_config_intr at803x_config_init at803x_get_features at803x_probe at803x_resume at803x_suspend at803x_get_stats at803x_get_strings at803x_get_sset_count at803x_get_wol at803x_set_wol at803x_read_page at803x_write_page at803x_debug_reg_mask    at803x.ko                                                                                                                                                                                                                    \       ,                   ,       +            ,       @            ,       U           ,       j     8      ,            d      ,                  ,                  ,                  ,                                                 #                 /      	       &    8             :    D      <       R                   [           $       c                   y                       `       p                                   x                 ,          @                       H                       !    p              -          9       @    0      a       P                 ^          H       m          !           @      .           p      z                                                   m                                                                	      0           	      N       3     
      :       B    @
            \            8       t    @                                                        
      9           `
                                                   0                         N           P             /                  C                \                 o          Z                                                           `                          X                                             0                   G                  ]    !       ;       x                                                                  #                                                                                                                                                                 +                   7                     I                     `                     n                                                                                                                                                                                                                                       #                     3                                          E                     X                     o                     w                                                                                                                                                                                                                  "            X       G                     Z                     m                                                                                                          __UNIQUE_ID_alias203 __UNIQUE_ID_alias202 __UNIQUE_ID_alias201 __UNIQUE_ID_alias200 __UNIQUE_ID_alias199 __UNIQUE_ID_alias198 __UNIQUE_ID_alias197 __UNIQUE_ID_alias196 __UNIQUE_ID_alias195 __UNIQUE_ID_alias194 __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 at803x_get_sset_count phy_module_init at803x_driver at803x_cable_test_start at803x_debug_reg_mask at803x_read_specific_status at803x_get_stats at803x_hw_stats at803x_cdt_wait_for_completion __func__.33 at803x_get_strings qca83xx_suspend at803x_resume at803x_suspend at803x_write_page at803x_read_page at803x_set_tunable at803x_set_wol offsets.39 at803x_handle_interrupt at803x_read_status at803x_probe phy_module_exit qca808x_soft_reset qca83xx_link_change_notify at803x_get_wol at803x_link_change_notify __UNIQUE_ID_ddebug423.0 __func__.37 at803x_config_aneg CSWTCH.111 qca808x_phy_ms_random_seed_set qca808x_config_init at803x_cable_test_get_status CSWTCH.65 ethtool_pair.38 at803x_get_tunable at803x_get_features qca808x_read_status qca808x_cable_test_start at803x_config_intr at803x_config_init qca808x_cable_test_get_status qca83xx_config_init qca83xx_resume __func__.36 atheros_tbl __UNIQUE_ID___addressable_cleanup_module511 __UNIQUE_ID___addressable_init_module510 __UNIQUE_ID_license417 __UNIQUE_ID_author416 __UNIQUE_ID_description415 phy_error genphy_setup_forced devm_kmalloc __this_module __mdiobus_read cleanup_module usleep_range_state phy_write_mmd ethnl_cable_test_fault_length __dynamic_dev_dbg __fentry__ init_module genphy_soft_reset phy_drivers_unregister genphy_resume __stack_chk_fail genphy_c45_fast_retrain __phy_modify genphy_c37_read_status _dev_err ethnl_cable_test_result genphy_read_abilities phy_modify_mmd mutex_lock phy_modify_mmd_changed genphy_read_lpa mdio_device_reset __x86_return_thunk genphy_c37_config_aneg strscpy genphy_c45_pma_setup_forced mutex_unlock __genphy_config_aneg mdiobus_write phy_drivers_register ktime_get phy_read_mmd phy_init_hw genphy_update_link phy_trigger_machine __mod_mdio__atheros_tbl_device_table genphy_read_status phy_modify_changed phy_resolve_aneg_pause msleep __SCT__might_resched get_random_u8 genphy_suspend              Y             l             Y   .          r   J          r   j          l             r             l             Y             r             h             r            l            Y   -         h   C         l   Z         h   A         Y   Z                           h            l            u            Y            t            ~   /         U   F         h   W         t   p         U            h               p                                    b            l            l            Y                              n               (      %         l   1         Y   V         k            l                        Y            k            Y            h            k            l            Y   -         `   A         Y   X         S   j         l   q         Y            {            l            l            v            l            Y   T                   e         V            k            h            h            l   -         e   S         e   m         x            Y            h            h            l            x            l            O            Y   8         w   w         i            l            l            a            |            Y            Q   	         l   '	         h   a	         e   	         Y   	         [   	         l   	         Y   	         l   
         Y   $
         h   6
         l   A
         Y   O
         l   
         h   
         h   
         h   
         h   
         h            h            j            }   (         j   2         }   J         r   e         r            r            r            r            r            l               @                                                       X   !         Y            g            q            q                                {            l            [   
         m   

         o   !
         Y   *
            a
         Y   
         e   
         l   
         V   
         _   
         V   
         V   
         V            V   %         V   <         V   S         V   j         V            V            V            V            Y            r            h                                  0       %         c   S         W            l            }            ^            Y   "         h   @         l   J         l   Q         Y   d         d            l            u            Y            u   8         z   r         l            Y            {   #         o   3         P   R         V   i         V            V            V            V            V            l            Y            h   (         r   5         l   L         h   \         l   u         h            r            Y            e            e            e            l   ,         f   S         `   j         p             k   !         Y   m         r            l            u            c            c   @         c   ^         c            u            W            u   '         W   >         u   l         W            u            W            Y            k            l   '         V   >         V   Z         r   z         r            r            r            r            r   *         r   J         r   f         r            r            Y            l            k            t            ~            U   	         h            t   7         U   O         h   p            `       {                             b            l            }            l             Y             R                        `                 s                `       
          \                                                                                                          (             @      0                   8                   @             0      H                   P                   X                   `             @      h             p      p                   x                                                                      	                   	                    
                   @
                                        
                   `
                                                           P                                                                                                                                                         W                    
                    i                                                           B                                                                             $      $                   (                   ,             i      0                   4                   8                   <                   @                   D                   H                   L                   P             	      T             	      X             	      \             5
      `             N
      d                   h                   l             
      p                   t             ?      x             I      |                                q                                      4                   [                                                                                                                                                                                                                       i                    n                                                                    $                    (                    ,                    0                    4                    8                    <                    @                    D                   H                   L                   P                   T                   X                   \             A      `             B      d             G      h             <      l             @      p             G      t             I      x             N      |             P                   T                   W                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 #                   $                   )                   0                   6                                                                                                                                                       $                  (                  ,            1      0            @      4            n      8            p      <            |      @                  D                  H                  L                  P                  T                  X                  \                  `                  d                  h                  l                  p                  t                  x                  |                                                                                                                                                                              
                                                                                                                                                                                                                                                                                                                                                                                          	                  	                  	                   P	                  `	                  e	                  s	                  	                  	                  	                  	                   	      $            	      (             
      ,            
      0            5
      4            :
      8            @
      <            U
      @            W
      D            Y
      H            [
      L            \
      P            ]
      T            d
      X                  \                  `                  d                  h                  l                  p                  t                  x                  |                                                 
                                                                                                             &                  '                                                                                                                                                                                     
                  
                  
                  
                   
                  &
                  T
                  Y
                  `
                  f
                  
                  
                                                                                                                                                                                                               $                  (                  ,                  0                  4                  8                  <                  @                  D                   H                  L            ?      P            N      T            P      X            W      \            X      `            Y      d                  h                  l                  p                  t                  x                   |                                                p                  q                  v                                                                                                                                                                                    1                  2                  4                  9                  S                  T                  X                  `                                                                                                                                                                                                                                                                                                                                                                           '      $            3      (            5      ,            7      0            8      4            <      8            C      <            |      @                  D                  H                  L                  P                  T                  X                  \                  `                  d                  h                  l                  p                  t                  x                  |                                                                                                                                                                                                                                                                                                                      *                    $       (         [           0                  8                  P                  X                  `                   p                  x                                                                   
                                                                           p                  <                                           (                  0                  P                  X                  p                  x             
                  @
                                   [                                                           P                                                                                 (                  0                  H                  P             
      p            @      x                                                                                       p                  T                                                                                                                    0            @
      h                   x                   `                             [                                                                                                                                          @	                   P	                   8
            H       `
         [           p
                  
                  
                  
                   
                  
                  
                                     (                               p       8         [           @                  H                  `            0      h                              	      
                    
                  
            @      
                            [                                                8            0      @                              	                                                        @                                  [                                                           0                        h            	                                                        @                  l                   	                  `
                                    P                                   ]                                                                                     0                  8             
      x                                                                    p                                                                          T                      Z                         }                    @                                                                             ~                                        ~           8         Z           P         T            .symtab .strtab .shstrtab .note.gnu.build-id .note.Linux .rela.text .rela.init.text .rela.exit.text .rela__mcount_loc .rodata.str1.1 .rela.smp_locks .rodata .rodata.str1.8 .modinfo .rela.return_sites .orc_unwind .rela.orc_unwind_ip __versions .rela__jump_table .rela.data .rela.exit.data .rela.init.data .rela__dyndbg .rela.static_call_sites .rela.gnu.linkonce.this_module .bss .comment .note.GNU-stack .BTF .gnu_debuglink                                                                                      @       $                              .                     d       <                              ?                                                         :      @               q            *                    J                     N                                    E      @                     `       *                    Z                     k                                    U      @               H      0       *                    j                     |                                   e      @               x      H      *   	                 w      2                                                                       d                                          @                            *                                         p                                          2                                                                                                                                  e#                                          @               ،            *                                         
$                                                        +                                         @               Ȑ      8      *                                         /                                                         ;                                          @                      H       *                                        ;      (                                   @               H            *                                        N                                         @               0             *                    &                    N                                    !     @               H             *                    6                    N      8                              1     @               `      `       *                    D                    0O                                    ?     @                     `       *   !                 \                    @O                    @               W     @                      0       *   #                 v                    R                                     {     0               R      P                                                  S                                                          S      	                                                  \                                                           ]            +   O                 	                      i                                                         P                                   0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  	<A<;8@lԨZ@&I?~ݎ`Zg^|g`?7Ch}jvt3<e=j	KVc8Z}t*o.(˂p,{}[Vq!q;>Fk
aȗNV"'n%G*FG8:$4ذ4B0%-ڡ߼BG:.ׅ6s Cd
@A2^|07E;8}2         ~Module signature appended~
 070701000A03A3000081A4000000000000000000000001682F6DA700002D0B000000CA0000000200000000000000000000004200000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/phy/ax88796b.ko ELF          >                    "          @     @ # "          GNU JכY:Tq        Linux                Linux   6.1.0-37-amd64      SH(  1H  1    x	H[    [    ff.            t    HH<$    H<$H         USH    Ņu	   u	[]    (  H  1    xIH߁    ⦃d        x  P<PuH    떉[]        H       H           H                                        Asix Electronics AX88772A Asix Electronics AX88772C Asix Electronics AX88796B license=GPL author=Michael Schmitz <schmitzmic@gmail.com> description=Asix PHY driver alias=mdio:0000000000111011000110000100???? alias=mdio:00000000001110110001100010000001 alias=mdio:00000000001110110001100001100001 depends=libphy retpoline=Y intree=Y name=ax88796b vermagic=6.1.0-37-amd64 SMP preempt mod_unload modversions                                                                                                                                                                                                             m    __fentry__                                              ![Ha    phy_drivers_register                                    XV    mdiobus_write                                           \(    genphy_soft_reset                                       9[    __x86_return_thunk                                           phy_drivers_unregister                                  ts    phy_init_hw                                             Z/    phy_start_aneg                                              genphy_update_link                                      ;    mdiobus_read                                            !5    genphy_read_lpa                                         >-k{    phy_resolve_aneg_linkmode                               a    genphy_suspend                                          |    genphy_resume                                           zR    module_layout                                           a; ; A;                                                                                                                                                                 a;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                A;                                                                                                                                                                                                                                                                                                                                                                         ax88796b                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0               z          
9             X              
Y A=      h                           @j                   [       P=       `=    p   p=    ǂ       
      
  =    a =    a mdio_device_id phy_module_exit phy_module_init asix_ax88772a_link_change_notify asix_ax88772a_read_status asix_soft_reset   ax88796b.ko o                                                                                                                                           V       ,                   ,       +            ,       @                   W                   d                   }            	                                     <                                       $                                                           2                               @       -       -    p              G                    P                   |                                                 .           :                                                   
                                        !                     3                     J                     X                     e                                                                                                                                                                                                                  __UNIQUE_ID_alias196 __UNIQUE_ID_alias195 __UNIQUE_ID_alias194 __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 phy_module_init asix_driver asix_soft_reset phy_module_exit asix_ax88772a_link_change_notify asix_ax88772a_read_status asix_tbl __UNIQUE_ID___addressable_cleanup_module319 __UNIQUE_ID___addressable_init_module318 __UNIQUE_ID_license317 __UNIQUE_ID_author316 __UNIQUE_ID_description315 __this_module cleanup_module __fentry__ init_module genphy_soft_reset phy_drivers_unregister genphy_resume mdiobus_read __mod_mdio__asix_tbl_device_table genphy_read_lpa __x86_return_thunk phy_start_aneg mdiobus_write phy_drivers_register phy_resolve_aneg_linkmode phy_init_hw genphy_update_link genphy_suspend                            )   (          !   .          '   A             O          '   \          ,   i          (   q             {          -             '             $             &             +             '                                                                    *                        
          "                                                           @                    p                     -                    N                                                                                                      '                    ,                    -                    2                    @                    W                     h       $             m       (             p       ,             v       0             w       4                    8                    <                    @                    D                    H                   L                     P                    T                     X                                                                       .                    #           0            p       h            @                                                       .                    #           p            4                                                                        8                     P                     .symtab .strtab .shstrtab .note.gnu.build-id .note.Linux .rela.text .rela.init.text .rela.exit.text .rela__mcount_loc .rodata.str1.1 .modinfo .rela.return_sites .orc_unwind .rela.orc_unwind_ip __versions .rela.data .rela.exit.data .rela.init.data .rela.gnu.linkonce.this_module .bss .comment .note.GNU-stack .BTF .gnu_debuglink                                                                                             @       $                              .                     d       <                              ?                                                         :      @                     h                           J                                                         E      @               @      `                            Z                                                         U      @                     0                            j                                                          e      @                     `           	                 w      2                     N                                                  ?      H                                                                                            @               0      `           
                                                                                               !      \                                    @                     (                                                                                                         @                                          @                                                                      
                                          @                                                                       
                                          @                                                                                            @                     @               !      0                                                                                          0                     P                             %                                                          5                           f                             :                     8                                                          H      h      !                    	                            $                                                   8!      I                             0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  u`ڠSr]8\Yvm(,׺uO,9.tQ%-	*$zaE_[nUfQGO]A6A}=<ߓ{j슼iEʾǥb8&-Ӄ\Vlm00O
A)jU:o=ɢ:zslbeWjjkؑn&xΗz@yy+Rzg:d\CO96_
'         ~Module signature appended~
 070701000A039B000081A4000000000000000000000001682F6DA70000AA13000000CA0000000200000000000000000000004500000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/phy/bcm-phy-lib.ko  ELF          >                              @     @ # "          GNU A*+_^gE[        Linux                Linux   6.1.0-37-amd64                 	(  H  ʺ       ff.     @     
ff |	ֺ   f ΋(  H      ff.     f    SH(  H         (     H  [    ff.     f    (  H         1҅O             SH(  
H      |      (     H      [%           U   SH(  H      x@(  H         x#Ѕu	1[]    H       []    H    ِ    UHSH    H3H    HH     H    u[]            Uκ   SH(  H      Ņx2(  H         (  1H         []    ff.         USH  HHp      H    H  Hp      []             ATIUS(  Ӻ   H      xQA$(  I$         x3!	9t!A$(  I$  ˺   []A\    1[]A\             AUAATAUSH  HHp      AAH    H  Hp      []A\A]    f    ATIUS(  Ӻ   H      xQA$(  I$         x3!	9t!A$(  I$  ˺   []A\    1[]A\             AUAATAUSH  HHp      AAH    H  Hp      []A\A]    f    SH(  H         x(  H     [    [    ff.         UΉպ   SH(  H      x(  H  ͺ   []    []         UΉպ   SH(  H      x(  H  ͺ   []    []         AWIAVAUATE1UHSHC$    A(  G$    I  G$        HxD   DV!HcJ#J#JT% II(u[]A\A]A^A_    ff.     @     U=     SH       ?   H߀@Dʺ=      <      H    xHH  H  HHʃ   Eʉ	!@Eʺ<       1[]    D      ATA   Uպ   SHH(  H      x~(  H         (     H  Ȁ    xFH  EHp      H
D	    H  D$Hp      D$H[]A\        USH  HHp      (  H         Ņx(  H         H  Hp      []    ff.         UH   S(  H      ÅxL   (  H  x?Ⱥ       Åu (  H         1҅NЉӉ[]           yÉ[]    ً(  [   H    ]    f.         SH(     H         (     H      x6@(     H      xH߹   1Ҿ   [    [    @     ATAUSH  HHp      (  H         Ņx(  H  A̺       H  Hp      []A\        AUAATA̹   Uպ   SH(  H      xZ(  H         (     H  Ȁ    x"EAH
[]D	A\A][]A\A]    D      ATAUSH  HHp      (  H         Ņx(  H  A̺       H  Hp      []A\        SH  HHp      (    H         x(        H      H  Hp      H  Hp      (    H         x(  H  1ɺ       H  [Hp      D      SH   H   2            H߾2       1ҹ   H߾3       1ҹi  H߾
       (  
   H         H  Hp      (    H         x(        H      H  Hp      H  Hp      (    H         x(  H  1ɺ       H  Hp      H߹  1Ҿ8       H߹?     8       H߹     8       H߹   1Ҿ:       H߹   1Ҿ9       1[    D      UH   p  SH(  H      (     H      x1ҨuU 1[]    (        H      (     H         uP1U ff.     f    SH@tW(        H      (     H      (     H  %        (   (     H      (     H      (  H  %  `   [Ѻ   DȀͩ    @     AT1ҹ   USH(  H      (     H         H  (  1ɺ	       H  Hp      @   (        H      Aąx=(        H      Aąu    $    H    Aċ(  ~     H      Ņx<(  H  1ɺ       ŅAD    $    H    H  Hp      []A\    ff.         1@            ATDAUSHA~
@   (     p  H      (     H         (  H  @   f
          (        H      (     H      %  @tAA	ă@DDȋ(       H  ͐[]A\    %  [   ]
  A\    []A\    ff.     f    AWAVIAUATUSHH H  Hp      @}  A(        I      AŅ  A(        I      AŅ    L    AŅ  A       L    Aą+  McEE1LLMIAHIAALL$PD$IC1    AE   LD,$MCD    LL$   LAAE̓MCED    AG1ɾ   LABω    D|$AAw$  L    =  tx1L    $w'  L    =  tx¾   L    AAw'  L    =  tx¾   L    AAw'  L    =  tx¾   L    @   E1A(  ~     I      Aąx#A(  I  1ɺ       AąEDI  Hp      DH[]A\A]A^A_      L    AąxA   tE1뵾  L    AąxEMfD      1@                                                                                                                                                                                                                                                                                                                                                                                                                                             kKbYP')V2kuJ\|~f7%)-"IJjQP^!fW=H}El59׬̧5ީfǘW;-"3.@c5֍ wt&tAgY<8wӆ__bcm_phy_write_exp  bcm_phy_write_exp  __bcm_phy_read_exp  bcm_phy_read_exp  __bcm_phy_modify_exp  bcm_phy_modify_exp  bcm54xx_auxctl_read  bcm54xx_auxctl_write  bcm_phy_write_misc  bcm_phy_read_misc  bcm_phy_ack_intr  bcm_phy_config_intr  bcm_phy_handle_interrupt  bcm_phy_read_shadow  bcm_phy_write_shadow  __bcm_phy_read_rdb  bcm_phy_read_rdb  __bcm_phy_write_rdb  bcm_phy_write_rdb  __bcm_phy_modify_rdb  bcm_phy_modify_rdb  bcm_phy_enable_apd  bcm_phy_set_eee  bcm_phy_downshift_get  bcm_phy_downshift_set  bcm_phy_get_sset_count  bcm_phy_get_strings  bcm_phy_get_stats  bcm_phy_r_rc_cal_reset  bcm_phy_28nm_a0b0_afe_config_init  bcm_phy_enable_jumbo  bcm_phy_cable_test_start  bcm_phy_cable_test_get_status  bcm_phy_cable_test_start_rdb  bcm_phy_cable_test_get_status_rdb                                                                                                                                                                                                                                                                                                          author=Broadcom Corporation license=GPL v2 description=Broadcom PHY Library depends=libphy retpoline=Y intree=Y name=bcm_phy_lib vermagic=6.1.0-37-amd64 SMP preempt mod_unload modversions  phy_receive_errors phy_serdes_ber_errors phy_local_rcvr_nok phy_remote_rcv_nok phy_false_carrier_sense_errors                                                                                                                                                                                                                                                                                                                                                                                                                                             (                                                                                (                                                                                                                          (    0  8  0  (                                                            (                                                                                                                                         (                 (                                                                                                                                                                                                                                                         (    0  8  H  8  0  (                     H                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          m    __fentry__                                              9[    __x86_return_thunk                                      XV    mdiobus_write                                           ;    mdiobus_read                                            D    phy_trigger_machine                                         phy_error                                               9d    strscpy                                                 hz    __mdiobus_write                                         ⨇    __mdiobus_read                                          KM    mutex_lock                                              82    mutex_unlock                                            0@    phy_read_mmd                                            o    phy_write_mmd                                           |ad    phy_modify                                              cȹ    ethnl_cable_test_result                                 脐    ethnl_cable_test_fault_length                           zR    module_layout                                                                   bcm_phy_lib                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0         p  p            
9             X              
Y          A=     d=    =    =    =    =      b         S $   @   G $   H     $   P          
\            ]              
^       
      
  XH   >    `       
      
  %>    b B>    ` `>    b       
      
  XH   y> K   >    f       
      
  y> K   >    h >    b >    b >    ǂ       
       
  U   0  I?      ?    m       
       
       ?    o -?    b       
      
    $   D?    r       
      
       Z?    t       
      
  5 K   p?    v       
      
  ? K   ?    x       
      
  ? &     &   G	  &   ?    z ?    z       
      
  ? &     &   ?    } ?    }       
      
  ? &   ?     @           
      
  U &     &   @           
      
  U &   +@           
     
  ?@     X@    b l@    b       
      
  S &   }@ &   @           
      
  S &   }@ &     &   @           
      
  
 &     &   @           
      
  
 &   @           
      
  S &     &   G	  &   @     @           
      
  S &   @     A           
      
  S &     &   A     -A     ETHTOOL_A_CABLE_RESULT_CODE_UNSPEC ETHTOOL_A_CABLE_RESULT_CODE_OK ETHTOOL_A_CABLE_RESULT_CODE_OPEN ETHTOOL_A_CABLE_RESULT_CODE_SAME_SHORT ETHTOOL_A_CABLE_RESULT_CODE_CROSS_SHORT bcm_phy_hw_stat bcm_phy_cable_test_get_status_rdb bcm_phy_cable_test_start_rdb bcm_phy_cable_test_get_status bcm_phy_cable_test_start is_rdb _bcm_phy_cable_test_get_status _bcm_phy_cable_test_start bcm_phy_enable_jumbo bcm_phy_28nm_a0b0_afe_config_init bcm_phy_r_rc_cal_reset bcm_phy_get_stats bcm_phy_get_strings bcm_phy_get_sset_count bcm_phy_downshift_set bcm_phy_downshift_get bcm_phy_set_eee dll_pwr_down bcm_phy_enable_apd rdb bcm_phy_modify_rdb __bcm_phy_modify_rdb bcm_phy_write_rdb __bcm_phy_write_rdb bcm_phy_read_rdb __bcm_phy_read_rdb bcm_phy_write_shadow bcm_phy_read_shadow bcm_phy_handle_interrupt bcm_phy_config_intr bcm_phy_ack_intr chl bcm_phy_read_misc bcm_phy_write_misc bcm54xx_auxctl_write bcm54xx_auxctl_read bcm_phy_modify_exp __bcm_phy_modify_exp bcm_phy_read_exp __bcm_phy_read_exp bcm_phy_write_exp __bcm_phy_write_exp bcm-phy-lib.ko  1                                                                                                                         
                     
 x               3     
                L     
 d               c     
                 ~     
 X                    
                     	                      
 |                    
 h                    
                     
 4               .    
 T               M    
 p               g    
                    
                    
 l                   
                    
                    
                    
 \                   
 @               1    
 t               G    
 8               c    
 <                   
 H                   
 P                   
 L                   
 `                   
                    
 D               .    
 ,               M    
 $               q    
 0                   
 (                   L                          @          [                  g       	           p              #           <       ;                   D           $       L                     j                         0                                        '                    h                   (                    ;               :                    W     <               r     M                    ,                   N                    c                                    	     d               &     w               E                   b     x                                        H                                                                                                :                    Y     t              v                                             8                                                           `                                   =                    ]                    {                         
                                                     	                   $	     P              B	                    a	     5              	                   	     6              	     I              	     $               	     J              
     [              2
     D              M
     \              k
     p              
     <               
     q              
                   
                   
                                      ?                    ^                   {                                                                                                                   *                   F     \              `                                                                                                 
                    $
                   E
                   h
                    
                   
     -              
                    
     .                   @                                  ;     A              \     X                                       Y                   {                   T               &     |              E                   f                                                                                                                    B     l               j                                                                             
                   ;     x               g            P                  T      K                x                                         +       !       c    	                                                                                           p          |       D           e                       g                                                            L                                          P      o       
          M                                P      ^           0                 `	             
          9           @      M                  C       .                     I                 F                     .	           M                                       !       Q                         
             \                     K    @      ^       )                 o                     	          t       w                     r
                                         
    
                                                                        P    0             	    @       3       E                 
          3      F    p      H           p                 `             	          E                                   (        __crc___bcm_phy_write_exp __crc_bcm_phy_write_exp __crc___bcm_phy_read_exp __crc_bcm_phy_read_exp __crc___bcm_phy_modify_exp __crc_bcm_phy_modify_exp __crc_bcm54xx_auxctl_read __crc_bcm54xx_auxctl_write __crc_bcm_phy_write_misc __crc_bcm_phy_read_misc __crc_bcm_phy_ack_intr __crc_bcm_phy_config_intr __crc_bcm_phy_handle_interrupt __crc_bcm_phy_read_shadow __crc_bcm_phy_write_shadow __crc___bcm_phy_read_rdb __crc_bcm_phy_read_rdb __crc___bcm_phy_write_rdb __crc_bcm_phy_write_rdb __crc___bcm_phy_modify_rdb __crc_bcm_phy_modify_rdb __crc_bcm_phy_enable_apd __crc_bcm_phy_set_eee __crc_bcm_phy_downshift_get __crc_bcm_phy_downshift_set __crc_bcm_phy_get_sset_count __crc_bcm_phy_get_strings __crc_bcm_phy_get_stats __crc_bcm_phy_r_rc_cal_reset __crc_bcm_phy_28nm_a0b0_afe_config_init __crc_bcm_phy_enable_jumbo __crc_bcm_phy_cable_test_start __crc_bcm_phy_cable_test_get_status __crc_bcm_phy_cable_test_start_rdb __crc_bcm_phy_cable_test_get_status_rdb __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 __kstrtab___bcm_phy_write_exp __kstrtabns___bcm_phy_write_exp __ksymtab___bcm_phy_write_exp __kstrtab_bcm_phy_write_exp __kstrtabns_bcm_phy_write_exp __ksymtab_bcm_phy_write_exp __kstrtab___bcm_phy_read_exp __kst// <ranges> -*- C++ -*-

// Copyright (C) 2019-2022 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 include/ranges
 *  This is a Standard C++ Library header.
 *  @ingroup concepts
 */

#ifndef _GLIBCXX_RANGES
#define _GLIBCXX_RANGES 1

#if __cplusplus > 201703L

#pragma GCC system_header

#include <concepts>

#if __cpp_lib_concepts

#include <compare>
#include <initializer_list>
#include <iterator>
#include <optional>
#include <span>
#include <tuple>
#include <bits/ranges_util.h>
#include <bits/refwrap.h>

/**
 * @defgroup ranges Ranges
 *
 * Components for dealing with ranges of elements.
 */

namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
namespace ranges
{
  // [range.access] customization point objects
  // [range.req] range and view concepts
  // [range.dangling] dangling iterator handling
  // Defined in <bits/ranges_base.h>

  // [view.interface] View interface
  // [range.subrange] Sub-ranges
  // Defined in <bits/ranges_util.h>

  // C++20 24.6 [range.factories] Range factories

  /// A view that contains no elements.
  template<typename _Tp> requires is_object_v<_Tp>
    class empty_view
    : public view_interface<empty_view<_Tp>>
    {
    public:
      static constexpr _Tp* begin() noexcept { return nullptr; }
      static constexpr _Tp* end() noexcept { return nullptr; }
      static constexpr _Tp* data() noexcept { return nullptr; }
      static constexpr size_t size() noexcept { return 0; }
      static constexpr bool empty() noexcept { return true; }
    };

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<empty_view<_Tp>> = true;

  namespace __detail
  {
    template<typename _Tp>
      concept __boxable = copy_constructible<_Tp> && is_object_v<_Tp>;

    template<__boxable _Tp>
      struct __box : std::optional<_Tp>
      {
	using std::optional<_Tp>::optional;

	constexpr
	__box()
	noexcept(is_nothrow_default_constructible_v<_Tp>)
	requires default_initializable<_Tp>
	: std::optional<_Tp>{std::in_place}
	{ }

	__box(const __box&) = default;
	__box(__box&&) = default;

	using std::optional<_Tp>::operator=;

	// _GLIBCXX_RESOLVE_LIB_DEFECTS
	// 3477. Simplify constraints for semiregular-box
	// 3572. copyable-box should be fully constexpr
	constexpr __box&
	operator=(const __box& __that)
	noexcept(is_nothrow_copy_constructible_v<_Tp>)
	requires (!copyable<_Tp>)
	{
	  if (this != std::__addressof(__that))
	    {
	      if ((bool)__that)
		this->emplace(*__that);
	      else
		this->reset();
	    }
	  return *this;
	}

	constexpr __box&
	operator=(__box&& __that)
	noexcept(is_nothrow_move_constructible_v<_Tp>)
	requires (!movable<_Tp>)
	{
	  if (this != std::__addressof(__that))
	    {
	      if ((bool)__that)
		this->emplace(std::move(*__that));
	      else
		this->reset();
	    }
	  return *this;
	}
      };

    // For types which are already copyable, this specialization of the
    // copyable wrapper stores the object directly without going through
    // std::optional.  It provides just the subset of the primary template's
    // API that we currently use.
    template<__boxable _Tp>
      requires copyable<_Tp> || (is_nothrow_move_constructible_v<_Tp>
				 && is_nothrow_copy_constructible_v<_Tp>)
      struct __box<_Tp>
      {
      private:
	[[no_unique_address]] _Tp _M_value = _Tp();

      public:
	__box() requires default_initializable<_Tp> = default;

	constexpr explicit
	__box(const _Tp& __t)
	noexcept(is_nothrow_copy_constructible_v<_Tp>)
	: _M_value(__t)
	{ }

	constexpr explicit
	__box(_Tp&& __t)
	noexcept(is_nothrow_move_constructible_v<_Tp>)
	: _M_value(std::move(__t))
	{ }

	template<typename... _Args>
	  requires constructible_from<_Tp, _Args...>
	  constexpr explicit
	  __box(in_place_t, _Args&&... __args)
	  noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
	  : _M_value(std::forward<_Args>(__args)...)
	  { }

	__box(const __box&) = default;
	__box(__box&&) = default;
	__box& operator=(const __box&) requires copyable<_Tp> = default;
	__box& operator=(__box&&) requires copyable<_Tp> = default;

	// When _Tp is nothrow_copy_constructible but not copy_assignable,
	// copy assignment is implemented via destroy-then-copy-construct.
	constexpr __box&
	operator=(const __box& __that) noexcept
	{
	  static_assert(is_nothrow_copy_constructible_v<_Tp>);
	  if (this != std::__addressof(__that))
	    {
	      _M_value.~_Tp();
	      std::construct_at(std::__addressof(_M_value), *__that);
	    }
	  return *this;
	}

	// Likewise for move assignment.
	constexpr __box&
	operator=(__box&& __that) noexcept
	{
	  static_assert(is_nothrow_move_constructible_v<_Tp>);
	  if (this != std::__addressof(__that))
	    {
	      _M_value.~_Tp();
	      std::construct_at(std::__addressof(_M_value), std::move(*__that));
	    }
	  return *this;
	}

	constexpr bool
	has_value() const noexcept
	{ return true; };

	constexpr _Tp&
	operator*() noexcept
	{ return _M_value; }

	constexpr const _Tp&
	operator*() const noexcept
	{ return _M_value; }

	constexpr _Tp*
	operator->() noexcept
	{ return std::__addressof(_M_value); }

	constexpr const _Tp*
	operator->() const noexcept
	{ return std::__addressof(_M_value); }
      };
  } // namespace __detail

  /// A view that contains exactly one element.
  template<copy_constructible _Tp> requires is_object_v<_Tp>
    class single_view : public view_interface<single_view<_Tp>>
    {
    public:
      single_view() requires default_initializable<_Tp> = default;

      constexpr explicit
      single_view(const _Tp& __t)
      noexcept(is_nothrow_copy_constructible_v<_Tp>)
      : _M_value(__t)
      { }

      constexpr explicit
      single_view(_Tp&& __t)
      noexcept(is_nothrow_move_constructible_v<_Tp>)
      : _M_value(std::move(__t))
      { }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3428. single_view's in place constructor should be explicit
      template<typename... _Args>
	requires constructible_from<_Tp, _Args...>
	constexpr explicit
	single_view(in_place_t, _Args&&... __args)
	noexcept(is_nothrow_constructible_v<_Tp, _Args...>)
	: _M_value{in_place, std::forward<_Args>(__args)...}
	{ }

      constexpr _Tp*
      begin() noexcept
      { return data(); }

      constexpr const _Tp*
      begin() const noexcept
      { return data(); }

      constexpr _Tp*
      end() noexcept
      { return data() + 1; }

      constexpr const _Tp*
      end() const noexcept
      { return data() + 1; }

      static constexpr size_t
      size() noexcept
      { return 1; }

      constexpr _Tp*
      data() noexcept
      { return _M_value.operator->(); }

      constexpr const _Tp*
      data() const noexcept
      { return _M_value.operator->(); }

    private:
      [[no_unique_address]] __detail::__box<_Tp> _M_value;
    };

  template<typename _Tp>
    single_view(_Tp) -> single_view<_Tp>;

  namespace __detail
  {
    template<typename _Wp>
      constexpr auto __to_signed_like(_Wp __w) noexcept
      {
	if constexpr (!integral<_Wp>)
	  return iter_difference_t<_Wp>();
	else if constexpr (sizeof(iter_difference_t<_Wp>) > sizeof(_Wp))
	  return iter_difference_t<_Wp>(__w);
	else if constexpr (sizeof(ptrdiff_t) > sizeof(_Wp))
	  return ptrdiff_t(__w);
	else if constexpr (sizeof(long long) > sizeof(_Wp))
	  return (long long)(__w);
#ifdef __SIZEOF_INT128__
	else if constexpr (__SIZEOF_INT128__ > sizeof(_Wp))
	  return __int128(__w);
#endif
	else
	  return __max_diff_type(__w);
      }

    template<typename _Wp>
      using __iota_diff_t = decltype(__to_signed_like(std::declval<_Wp>()));

    template<typename _It>
      concept __decrementable = incrementable<_It>
	&& requires(_It __i)
	{
	    { --__i } -> same_as<_It&>;
	    { __i-- } -> same_as<_It>;
	};

    template<typename _It>
      concept __advanceable = __decrementable<_It> && totally_ordered<_It>
	&& requires( _It __i, const _It __j, const __iota_diff_t<_It> __n)
	{
	  { __i += __n } -> same_as<_It&>;
	  { __i -= __n } -> same_as<_It&>;
	  _It(__j + __n);
	  _It(__n + __j);
	  _It(__j - __n);
	  { __j - __j } -> convertible_to<__iota_diff_t<_It>>;
	};

    template<typename _Winc>
      struct __iota_view_iter_cat
      { };

    template<incrementable _Winc>
      struct __iota_view_iter_cat<_Winc>
      { using iterator_category = input_iterator_tag; };
  } // namespace __detail

  template<weakly_incrementable _Winc,
	   semiregular _Bound = unreachable_sentinel_t>
    requires std::__detail::__weakly_eq_cmp_with<_Winc, _Bound>
      && copyable<_Winc>
    class iota_view : public view_interface<iota_view<_Winc, _Bound>>
    {
    private:
      struct _Sentinel;

      struct _Iterator : __detail::__iota_view_iter_cat<_Winc>
      {
      private:
	static auto
	_S_iter_concept()
	{
	  using namespace __detail;
	  if constexpr (__advanceable<_Winc>)
	    return random_access_iterator_tag{};
	  else if constexpr (__decrementable<_Winc>)
	    return bidirectional_iterator_tag{};
	  else if constexpr (incrementable<_Winc>)
	    return forward_iterator_tag{};
	  else
	    return input_iterator_tag{};
	}

      public:
	using iterator_concept = decltype(_S_iter_concept());
	// iterator_category defined in __iota_view_iter_cat
	using value_type = _Winc;
	using difference_type = __detail::__iota_diff_t<_Winc>;

	_Iterator() requires default_initializable<_Winc> = default;

	constexpr explicit
	_Iterator(_Winc __value)
	: _M_value(__value) { }

	constexpr _Winc
	operator*() const noexcept(is_nothrow_copy_constructible_v<_Winc>)
	{ return _M_value; }

	constexpr _Iterator&
	operator++()
	{
	  ++_M_value;
	  return *this;
	}

	constexpr void
	operator++(int)
	{ ++*this; }

	constexpr _Iterator
	operator++(int) requires incrementable<_Winc>
	{
	  auto __tmp = *this;
	  ++*this;
	  return __tmp;
	}

	constexpr _Iterator&
	operator--() requires __detail::__decrementable<_Winc>
	{
	  --_M_value;
	  return *this;
	}

	constexpr _Iterator
	operator--(int) requires __detail::__decrementable<_Winc>
	{
	  auto __tmp = *this;
	  --*this;
	  return __tmp;
	}

	constexpr _Iterator&
	operator+=(difference_type __n) requires __detail::__advanceable<_Winc>
	{
	  using __detail::__is_integer_like;
	  using __detail::__is_signed_integer_like;
	  if constexpr (__is_integer_like<_Winc>
	      && !__is_signed_integer_like<_Winc>)
	    {
	      if (__n >= difference_type(0))
		_M_value += static_cast<_Winc>(__n);
	      else
		_M_value -= static_cast<_Winc>(-__n);
	    }
	  else
	    _M_value += __n;
	  return *this;
	}

	constexpr _Iterator&
	operator-=(difference_type __n) requires __detail::__advanceable<_Winc>
	{
	  using __detail::__is_integer_like;
	  using __detail::__is_signed_integer_like;
	  if constexpr (__is_integer_like<_Winc>
	      && !__is_signed_integer_like<_Winc>)
	    {
	      if (__n >= difference_type(0))
		_M_value -= static_cast<_Winc>(__n);
	      else
		_M_value += static_cast<_Winc>(-__n);
	    }
	  else
	    _M_value -= __n;
	  return *this;
	}

	constexpr _Winc
	operator[](difference_type __n) const
	requires __detail::__advanceable<_Winc>
	{ return _Winc(_M_value + __n); }

	friend constexpr bool
	operator==(const _Iterator& __x, const _Iterator& __y)
	requires equality_comparable<_Winc>
	{ return __x._M_value == __y._M_value; }

	friend constexpr bool
	operator<(const _Iterator& __x, const _Iterator& __y)
	requires totally_ordered<_Winc>
	{ return __x._M_value < __y._M_value; }

	friend constexpr bool
	operator>(const _Iterator& __x, const _Iterator& __y)
	  requires totally_ordered<_Winc>
	{ return __y < __x; }

	friend constexpr bool
	operator<=(const _Iterator& __x, const _Iterator& __y)
	  requires totally_ordered<_Winc>
	{ return !(__y < __x); }

	friend constexpr bool
	operator>=(const _Iterator& __x, const _Iterator& __y)
	  requires totally_ordered<_Winc>
	{ return !(__x < __y); }

#ifdef __cpp_lib_three_way_comparison
	friend constexpr auto
	operator<=>(const _Iterator& __x, const _Iterator& __y)
	  requires totally_ordered<_Winc> && three_way_comparable<_Winc>
	{ return __x._M_value <=> __y._M_value; }
#endif

	friend constexpr _Iterator
	operator+(_Iterator __i, difference_type __n)
	  requires __detail::__advanceable<_Winc>
	{
	  __i += __n;
	  return __i;
	}

	friend constexpr _Iterator
	operator+(difference_type __n, _Iterator __i)
	  requires __detail::__advanceable<_Winc>
	{ return __i += __n; }

	friend constexpr _Iterator
	operator-(_Iterator __i, difference_type __n)
	  requires __detail::__advanceable<_Winc>
	{
	  __i -= __n;
	  return __i;
	}

	friend constexpr difference_type
	operator-(const _Iterator& __x, const _Iterator& __y)
	  requires __detail::__advanceable<_Winc>
	{
	  using __detail::__is_integer_like;
	  using __detail::__is_signed_integer_like;
	  using _Dt = difference_type;
	  if constexpr (__is_integer_like<_Winc>)
	    {
	      if constexpr (__is_signed_integer_like<_Winc>)
		return _Dt(_Dt(__x._M_value) - _Dt(__y._M_value));
	      else
		return (__y._M_value > __x._M_value)
		  ? _Dt(-_Dt(__y._M_value - __x._M_value))
		  : _Dt(__x._M_value - __y._M_value);
	    }
	  else
	    return __x._M_value - __y._M_value;
	}

      private:
	_Winc _M_value = _Winc();

	friend iota_view;
        friend _Sentinel;
      };

      struct _Sentinel
      {
      private:
	constexpr bool
	_M_equal(const _Iterator& __x) const
	{ return __x._M_value == _M_bound; }

	constexpr auto
	_M_distance_from(const _Iterator& __x) const
	{ return _M_bound - __x._M_value; }

	_Bound _M_bound = _Bound();

      public:
	_Sentinel() = default;

	constexpr explicit
	_Sentinel(_Bound __bound)
	: _M_bound(__bound) { }

	friend constexpr bool
	operator==(const _Iterator& __x, const _Sentinel& __y)
	{ return __y._M_equal(__x); }

	friend constexpr iter_difference_t<_Winc>
	operator-(const _Iterator& __x, const _Sentinel& __y)
	  requires sized_sentinel_for<_Bound, _Winc>
	{ return -__y._M_distance_from(__x); }

	friend constexpr iter_difference_t<_Winc>
	operator-(const _Sentinel& __x, const _Iterator& __y)
	  requires sized_sentinel_for<_Bound, _Winc>
	{ return __x._M_distance_from(__y); }

	friend iota_view;
      };

      _Winc _M_value = _Winc();
      [[no_unique_address]] _Bound _M_bound = _Bound();

    public:
      iota_view() requires default_initializable<_Winc> = default;

      constexpr explicit
      iota_view(_Winc __value)
      : _M_value(__value)
      { }

      constexpr
      iota_view(type_identity_t<_Winc> __value,
		type_identity_t<_Bound> __bound)
      : _M_value(__value), _M_bound(__bound)
      {
	if constexpr (totally_ordered_with<_Winc, _Bound>)
	  __glibcxx_assert( bool(__value <= __bound) );
      }

      constexpr
      iota_view(_Iterator __first, _Iterator __last)
	requires same_as<_Winc, _Bound>
	: iota_view(__first._M_value, __last._M_value)
      { }

      constexpr
      iota_view(_Iterator __first, unreachable_sentinel_t __last)
	requires same_as<_Bound, unreachable_sentinel_t>
	: iota_view(__first._M_value, __last)
      { }

      constexpr
      iota_view(_Iterator __first, _Sentinel __last)
	requires (!same_as<_Winc, _Bound>) && (!same_as<_Bound, unreachable_sentinel_t>)
	: iota_view(__first._M_value, __last._M_bound)
      { }

      constexpr _Iterator
      begin() const { return _Iterator{_M_value}; }

      constexpr auto
      end() const
      {
	if constexpr (same_as<_Bound, unreachable_sentinel_t>)
	  return unreachable_sentinel;
	else
	  return _Sentinel{_M_bound};
      }

      constexpr _Iterator
      end() const requires same_as<_Winc, _Bound>
      { return _Iterator{_M_bound}; }

      constexpr auto
      size() const
      requires (same_as<_Winc, _Bound> && __detail::__advanceable<_Winc>)
      || (integral<_Winc> && integral<_Bound>)
      || sized_sentinel_for<_Bound, _Winc>
      {
	using __detail::__is_integer_like;
	using __detail::__to_unsigned_like;
	if constexpr (integral<_Winc> && integral<_Bound>)
	  {
	    using _Up = make_unsigned_t<decltype(_M_bound - _M_value)>;
	    return _Up(_M_bound) - _Up(_M_value);
	  }
	else if constexpr (__is_integer_like<_Winc>)
	  return __to_unsigned_like(_M_bound) - __to_unsigned_like(_M_value);
	else
	  return __to_unsigned_like(_M_bound - _M_value);
      }
    };

  template<typename _Winc, typename _Bound>
    requires (!__detail::__is_integer_like<_Winc>
	|| !__detail::__is_integer_like<_Bound>
	|| (__detail::__is_signed_integer_like<_Winc>
	    == __detail::__is_signed_integer_like<_Bound>))
    iota_view(_Winc, _Bound) -> iota_view<_Winc, _Bound>;

  template<typename _Winc, typename _Bound>
    inline constexpr bool
      enable_borrowed_range<iota_view<_Winc, _Bound>> = true;

namespace views
{
  template<typename _Tp>
    inline constexpr empty_view<_Tp> empty{};

  struct _Single
  {
    template<typename _Tp>
      [[nodiscard]]
      constexpr auto
      operator()(_Tp&& __e) const
      noexcept(noexcept(single_view<decay_t<_Tp>>(std::forward<_Tp>(__e))))
      { return single_view<decay_t<_Tp>>(std::forward<_Tp>(__e)); }
  };

  inline constexpr _Single single{};

  struct _Iota
  {
    template<typename _Tp>
      [[nodiscard]]
      constexpr auto
      operator()(_Tp&& __e) const
      { return iota_view(std::forward<_Tp>(__e)); }

    template<typename _Tp, typename _Up>
      [[nodiscard]]
      constexpr auto
      operator()(_Tp&& __e, _Up&& __f) const
      { return iota_view(std::forward<_Tp>(__e), std::forward<_Up>(__f)); }
  };

  inline constexpr _Iota iota{};
} // namespace views

  namespace __detail
  {
    template<typename _Val, typename _CharT, typename _Traits>
      concept __stream_extractable
	= requires(basic_istream<_CharT, _Traits>& is, _Val& t) { is >> t; };
  } // namespace __detail

  template<movable _Val, typename _CharT,
	   typename _Traits = char_traits<_CharT>>
    requires default_initializable<_Val>
      && __detail::__stream_extractable<_Val, _CharT, _Traits>
    class basic_istream_view
    : public view_interface<basic_istream_view<_Val, _CharT, _Traits>>
    {
    public:
      constexpr explicit
      basic_istream_view(basic_istream<_CharT, _Traits>& __stream)
	: _M_stream(std::__addressof(__stream))
      { }

      constexpr auto
      begin()
      {
	*_M_stream >> _M_object;
	return _Iterator{this};
      }

      constexpr default_sentinel_t
      end() const noexcept
      { return default_sentinel; }

    private:
      basic_istream<_CharT, _Traits>* _M_stream;
      _Val _M_object = _Val();

      struct _Iterator
      {
      public:
	using iterator_concept = input_iterator_tag;
	using difference_type = ptrdiff_t;
	using value_type = _Val;

	constexpr explicit
	_Iterator(basic_istream_view* __parent) noexcept
	  : _M_parent(__parent)
	{ }

	_Iterator(const _Iterator&) = delete;
	_Iterator(_Iterator&&) = default;
	_Iterator& operator=(const _Iterator&) = delete;
	_Iterator& operator=(_Iterator&&) = default;

	_Iterator&
	operator++()
	{
	  *_M_parent->_M_stream >> _M_parent->_M_object;
	  return *this;
	}

	void
	operator++(int)
	{ ++*this; }

	_Val&
	operator*() const
	{ return _M_parent->_M_object; }

	friend bool
	operator==(const _Iterator& __x, default_sentinel_t)
	{ return __x._M_at_end(); }

      private:
	basic_istream_view* _M_parent;

	bool
	_M_at_end() const
	{ return !*_M_parent->_M_stream; }
      };

      friend _Iterator;
    };

  template<typename _Val>
    using istream_view = basic_istream_view<_Val, char>;

  template<typename _Val>
    using wistream_view = basic_istream_view<_Val, wchar_t>;

namespace views
{
  template<typename _Tp>
    struct _Istream
    {
      template<typename _CharT, typename _Traits>
	[[nodiscard]]
	constexpr auto
	operator()(basic_istream<_CharT, _Traits>& __e) const
	{ return basic_istream_view<_Tp, _CharT, _Traits>(__e); }
    };

  template<typename _Tp>
    inline constexpr _Istream<_Tp> istream;
}

  // C++20 24.7 [range.adaptors] Range adaptors

namespace __detail
{
  struct _Empty { };

  // Alias for a type that is conditionally present
  // (and is an empty type otherwise).
  // Data members using this alias should use [[no_unique_address]] so that
  // they take no space when not needed.
  template<bool _Present, typename _Tp>
    using __maybe_present_t = __conditional_t<_Present, _Tp, _Empty>;

  // Alias for a type that is conditionally const.
  template<bool _Const, typename _Tp>
    using __maybe_const_t = __conditional_t<_Const, const _Tp, _Tp>;

} // namespace __detail

namespace views::__adaptor
{
  // True if the range adaptor _Adaptor can be applied with _Args.
  template<typename _Adaptor, typename... _Args>
    concept __adaptor_invocable
      = requires { std::declval<_Adaptor>()(declval<_Args>()...); };

  // True if the range adaptor non-closure _Adaptor can be partially applied
  // with _Args.
  template<typename _Adaptor, typename... _Args>
    concept __adaptor_partial_app_viable = (_Adaptor::_S_arity > 1)
      && (sizeof...(_Args) == _Adaptor::_S_arity - 1)
      && (constructible_from<decay_t<_Args>, _Args> && ...);

  template<typename _Adaptor, typename... _Args>
    struct _Partial;

  template<typename _Lhs, typename _Rhs>
    struct _Pipe;

  // The base class of every range adaptor closure.
  //
  // The derived class should define the optional static data member
  // _S_has_simple_call_op to true if the behavior of this adaptor is
  // independent of the constness/value category of the adaptor object.
  struct _RangeAdaptorClosure
  {
    // range | adaptor is equivalent to adaptor(range).
    template<typename _Self, typename _Range>
      requires derived_from<remove_cvref_t<_Self>, _RangeAdaptorClosure>
	&& __adaptor_invocable<_Self, _Range>
      friend constexpr auto
      operator|(_Range&& __r, _Self&& __self)
      { return std::forward<_Self>(__self)(std::forward<_Range>(__r)); }

    // Compose the adaptors __lhs and __rhs into a pipeline, returning
    // another range adaptor closure object.
    template<typename _Lhs, typename _Rhs>
      requires derived_from<_Lhs, _RangeAdaptorClosure>
	&& derived_from<_Rhs, _RangeAdaptorClosure>
      friend constexpr auto
      operator|(_Lhs __lhs, _Rhs __rhs)
      { return _Pipe<_Lhs, _Rhs>{std::move(__lhs), std::move(__rhs)}; }
  };

  // The base class of every range adaptor non-closure.
  //
  // The static data member _Derived::_S_arity must contain the total number of
  // arguments that the adaptor takes, and the class _Derived must introduce
  // _RangeAdaptor::operator() into the class scope via a using-declaration.
  //
  // The optional static data member _Derived::_S_has_simple_extra_args should
  // be defined to true if the behavior of this adaptor is independent of the
  // constness/value category of the extra arguments.  This data member could
  // also be defined as a variable template parameterized by the types of the
  // extra arguments.
  template<typename _Derived>
    struct _RangeAdaptor
    {
      // Partially apply the arguments __args to the range adaptor _Derived,
      // returning a range adaptor closure object.
      template<typename... _Args>
	requires __adaptor_partial_app_viable<_Derived, _Args...>
	constexpr auto
	operator()(_Args&&... __args) const
	{
	  return _Partial<_Derived, decay_t<_Args>...>{std::forward<_Args>(__args)...};
	}
    };

  // True if the range adaptor closure _Adaptor has a simple operator(), i.e.
  // one that's not overloaded according to constness or value category of the
  // _Adaptor object.
  template<typename _Adaptor>
    concept __closure_has_simple_call_op = _Adaptor::_S_has_simple_call_op;

  // True if the behavior of the range adaptor non-closure _Adaptor is
  // independent of the value category of its extra arguments _Args.
  template<typename _Adaptor, typename... _Args>
    concept __adaptor_has_simple_extra_args = _Adaptor::_S_has_simple_extra_args
      || _Adaptor::template _S_has_simple_extra_args<_Args...>;

  // A range adaptor closure that represents partial application of
  // the range adaptor _Adaptor with arguments _Args.
  template<typename _Adaptor, typename... _Args>
    struct _Partial : _RangeAdaptorClosure
    {
      tuple<_Args...> _M_args;

      constexpr
      _Partial(_Args... __args)
	: _M_args(std::move(__args)...)
      { }

      // Invoke _Adaptor with arguments __r, _M_args... according to the
      // value category of this _Partial object.
      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
	constexpr auto
	operator()(_Range&& __r) const &
	{
	  auto __forwarder = [&__r] (const auto&... __args) {
	    return _Adaptor{}(std::forward<_Range>(__r), __args...);
	  };
	  return std::apply(__forwarder, _M_args);
	}

      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, _Args...>
	constexpr auto
	operator()(_Range&& __r) &&
	{
	  auto __forwarder = [&__r] (auto&... __args) {
	    return _Adaptor{}(std::forward<_Range>(__r), std::move(__args)...);
	  };
	  return std::apply(__forwarder, _M_args);
	}

      template<typename _Range>
	constexpr auto
	operator()(_Range&& __r) const && = delete;
    };

  // A lightweight specialization of the above primary template for
  // the common case where _Adaptor accepts a single extra argument.
  template<typename _Adaptor, typename _Arg>
    struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
    {
      _Arg _M_arg;

      constexpr
      _Partial(_Arg __arg)
	: _M_arg(std::move(__arg))
      { }

      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
	constexpr auto
	operator()(_Range&& __r) const &
	{ return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }

      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, _Arg>
	constexpr auto
	operator()(_Range&& __r) &&
	{ return _Adaptor{}(std::forward<_Range>(__r), std::move(_M_arg)); }

      template<typename _Range>
	constexpr auto
	operator()(_Range&& __r) const && = delete;
    };

  // Partial specialization of the primary template for the case where the extra
  // arguments of the adaptor can always be safely and efficiently forwarded by
  // const reference.  This lets us get away with a single operator() overload,
  // which makes overload resolution failure diagnostics more concise.
  template<typename _Adaptor, typename... _Args>
    requires __adaptor_has_simple_extra_args<_Adaptor, _Args...>
      && (is_trivially_copyable_v<_Args> && ...)
    struct _Partial<_Adaptor, _Args...> : _RangeAdaptorClosure
    {
      tuple<_Args...> _M_args;

      constexpr
      _Partial(_Args... __args)
	: _M_args(std::move(__args)...)
      { }

      // Invoke _Adaptor with arguments __r, const _M_args&... regardless
      // of the value category of this _Partial object.
      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, const _Args&...>
	constexpr auto
	operator()(_Range&& __r) const
	{
	  auto __forwarder = [&__r] (const auto&... __args) {
	    return _Adaptor{}(std::forward<_Range>(__r), __args...);
	  };
	  return std::apply(__forwarder, _M_args);
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

  // A lightweight specialization of the above template for the common case
  // where _Adaptor accepts a single extra argument.
  template<typename _Adaptor, typename _Arg>
    requires __adaptor_has_simple_extra_args<_Adaptor, _Arg>
      && is_trivially_copyable_v<_Arg>
    struct _Partial<_Adaptor, _Arg> : _RangeAdaptorClosure
    {
      _Arg _M_arg;

      constexpr
      _Partial(_Arg __arg)
	: _M_arg(std::move(__arg))
      { }

      template<typename _Range>
	requires __adaptor_invocable<_Adaptor, _Range, const _Arg&>
	constexpr auto
	operator()(_Range&& __r) const
	{ return _Adaptor{}(std::forward<_Range>(__r), _M_arg); }

      static constexpr bool _S_has_simple_call_op = true;
    };

  template<typename _Lhs, typename _Rhs, typename _Range>
    concept __pipe_invocable
      = requires { std::declval<_Rhs>()(std::declval<_Lhs>()(std::declval<_Range>())); };

  // A range adaptor closure that represents composition of the range
  // adaptor closures _Lhs and _Rhs.
  template<typename _Lhs, typename _Rhs>
    struct _Pipe : _RangeAdaptorClosure
    {
      [[no_unique_address]] _Lhs _M_lhs;
      [[no_unique_address]] _Rhs _M_rhs;

      constexpr
      _Pipe(_Lhs __lhs, _Rhs __rhs)
	: _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
      { }

      // Invoke _M_rhs(_M_lhs(__r)) according to the value category of this
      // range adaptor closure object.
      template<typename _Range>
	requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
	constexpr auto
	operator()(_Range&& __r) const &
	{ return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }

      template<typename _Range>
	requires __pipe_invocable<_Lhs, _Rhs, _Range>
	constexpr auto
	operator()(_Range&& __r) &&
	{ return std::move(_M_rhs)(std::move(_M_lhs)(std::forward<_Range>(__r))); }

      template<typename _Range>
	constexpr auto
	operator()(_Range&& __r) const && = delete;
    };

  // A partial specialization of the above primary template for the case where
  // both adaptor operands have a simple operator().  This in turn lets us
  // implement composition using a single simple operator(), which makes
  // overload resolution failure diagnostics more concise.
  template<typename _Lhs, typename _Rhs>
    requires __closure_has_simple_call_op<_Lhs>
      && __closure_has_simple_call_op<_Rhs>
    struct _Pipe<_Lhs, _Rhs> : _RangeAdaptorClosure
    {
      [[no_unique_address]] _Lhs _M_lhs;
      [[no_unique_address]] _Rhs _M_rhs;

      constexpr
      _Pipe(_Lhs __lhs, _Rhs __rhs)
	: _M_lhs(std::move(__lhs)), _M_rhs(std::move(__rhs))
      { }

      template<typename _Range>
	requires __pipe_invocable<const _Lhs&, const _Rhs&, _Range>
	constexpr auto
	operator()(_Range&& __r) const
	{ return _M_rhs(_M_lhs(std::forward<_Range>(__r))); }

      static constexpr bool _S_has_simple_call_op = true;
    };
} // namespace views::__adaptor

  template<range _Range> requires is_object_v<_Range>
    class ref_view : public view_interface<ref_view<_Range>>
    {
    private:
      _Range* _M_r;

      static void _S_fun(_Range&); // not defined
      static void _S_fun(_Range&&) = delete;

    public:
      template<__detail::__different_from<ref_view> _Tp>
	requires convertible_to<_Tp, _Range&>
	  && requires { _S_fun(declval<_Tp>()); }
	constexpr
	ref_view(_Tp&& __t)
	noexcept(noexcept(static_cast<_Range&>(std::declval<_Tp>())))
	  : _M_r(std::__addressof(static_cast<_Range&>(std::forward<_Tp>(__t))))
	{ }

      constexpr _Range&
      base() const
      { return *_M_r; }

      constexpr iterator_t<_Range>
      begin() const
      { return ranges::begin(*_M_r); }

      constexpr sentinel_t<_Range>
      end() const
      { return ranges::end(*_M_r); }

      constexpr bool
      empty() const requires requires { ranges::empty(*_M_r); }
      { return ranges::empty(*_M_r); }

      constexpr auto
      size() const requires sized_range<_Range>
      { return ranges::size(*_M_r); }

      constexpr auto
      data() const requires contiguous_range<_Range>
      { return ranges::data(*_M_r); }
    };

  template<typename _Range>
    ref_view(_Range&) -> ref_view<_Range>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<ref_view<_Tp>> = true;

  template<range _Range>
    requires movable<_Range>
      && (!__detail::__is_initializer_list<remove_cv_t<_Range>>)
    class owning_view : public view_interface<owning_view<_Range>>
    {
    private:
      _Range _M_r = _Range();

    public:
      owning_view() requires default_initializable<_Range> = default;

      constexpr
      owning_view(_Range&& __t)
      noexcept(is_nothrow_move_constructible_v<_Range>)
	: _M_r(std::move(__t))
      { }

      owning_view(owning_view&&) = default;
      owning_view& operator=(owning_view&&) = default;

      constexpr _Range&
      base() & noexcept
      { return _M_r; }

      constexpr const _Range&
      base() const& noexcept
      { return _M_r; }

      constexpr _Range&&
      base() && noexcept
      { return std::move(_M_r); }

      constexpr const _Range&&
      base() const&& noexcept
      { return std::move(_M_r); }

      constexpr iterator_t<_Range>
      begin()
      { return ranges::begin(_M_r); }

      constexpr sentinel_t<_Range>
      end()
      { return ranges::end(_M_r); }

      constexpr auto
      begin() const requires range<const _Range>
      { return ranges::begin(_M_r); }

      constexpr auto
      end() const requires range<const _Range>
      { return ranges::end(_M_r); }

      constexpr bool
      empty() requires requires { ranges::empty(_M_r); }
      { return ranges::empty(_M_r); }

      constexpr bool
      empty() const requires requires { ranges::empty(_M_r); }
      { return ranges::empty(_M_r); }

      constexpr auto
      size() requires sized_range<_Range>
      { return ranges::size(_M_r); }

      constexpr auto
      size() const requires sized_range<const _Range>
      { return ranges::size(_M_r); }

      constexpr auto
      data() requires contiguous_range<_Range>
      { return ranges::data(_M_r); }

      constexpr auto
      data() const requires contiguous_range<const _Range>
      { return ranges::data(_M_r); }
    };

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<owning_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	concept __can_ref_view = requires { ref_view{std::declval<_Range>()}; };

      template<typename _Range>
	concept __can_owning_view = requires { owning_view{std::declval<_Range>()}; };
    } // namespace __detail

    struct _All : __adaptor::_RangeAdaptorClosure
    {
      template<typename _Range>
	static constexpr bool
	_S_noexcept()
	{
	  if constexpr (view<decay_t<_Range>>)
	    return is_nothrow_constructible_v<decay_t<_Range>, _Range>;
	  else if constexpr (__detail::__can_ref_view<_Range>)
	    return true;
	  else
	    return noexcept(owning_view{std::declval<_Range>()});
	}

      template<viewable_range _Range>
	requires view<decay_t<_Range>>
	  || __detail::__can_ref_view<_Range>
	  || __detail::__can_owning_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	noexcept(_S_noexcept<_Range>())
	{
	  if constexpr (view<decay_t<_Range>>)
	    return std::forward<_Range>(__r);
	  else if constexpr (__detail::__can_ref_view<_Range>)
	    return ref_view{std::forward<_Range>(__r)};
	  else
	    return owning_view{std::forward<_Range>(__r)};
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _All all;

    template<viewable_range _Range>
      using all_t = decltype(all(std::declval<_Range>()));
  } // namespace views

  namespace __detail
  {
    template<typename _Tp>
      struct __non_propagating_cache
      {
	// When _Tp is not an object type (e.g. is a reference type), we make
	// __non_propagating_cache<_Tp> empty rather than ill-formed so that
	// users can easily conditionally declare data members with this type
	// (such as join_view::_M_inner).
      };

    template<typename _Tp>
      requires is_object_v<_Tp>
      struct __non_propagating_cache<_Tp>
      : protected _Optional_base<_Tp>
      {
	__non_propagating_cache() = default;

	constexpr
	__non_propagating_cache(const __non_propagating_cache&) noexcept
	{ }

	constexpr
	__non_propagating_cache(__non_propagating_cache&& __other) noexcept
	{ __other._M_reset(); }

	constexpr __non_propagating_cache&
	operator=(const __non_propagating_cache& __other) noexcept
	{
	  if (std::__addressof(__other) != this)
	    this->_M_reset();
	  return *this;
	}

	constexpr __non_propagating_cache&
	operator=(__non_propagating_cache&& __other) noexcept
	{
	  this->_M_reset();
	  __other._M_reset();
	  return *this;
	}

	constexpr __non_propagating_cache&
	operator=(_Tp __val)
	{
	  this->_M_reset();
	  this->_M_payload._M_construct(std::move(__val));
	  return *this;
	}

	constexpr explicit
	operator bool() const noexcept
	{ return this->_M_is_engaged(); }

	constexpr _Tp&
	operator*() noexcept
	{ return this->_M_get(); }

	constexpr const _Tp&
	operator*() const noexcept
	{ return this->_M_get(); }

	template<typename _Iter>
	  constexpr _Tp&
	  _M_emplace_deref(const _Iter& __i)
	  {
	    this->_M_reset();
	    auto __f = [] (auto& __x) { return *__x; };
	    this->_M_payload._M_apply(_Optional_func{__f}, __i);
	    return this->_M_get();
	  }
      };

    template<range _Range>
      struct _CachedPosition
      {
	constexpr bool
	_M_has_value() const
	{ return false; }

	constexpr iterator_t<_Range>
	_M_get(const _Range&) const
	{
	  __glibcxx_assert(false);
	  __builtin_unreachable();
	}

	constexpr void
	_M_set(const _Range&, const iterator_t<_Range>&) const
	{ }
      };

    template<forward_range _Range>
      struct _CachedPosition<_Range>
	: protected __non_propagating_cache<iterator_t<_Range>>
      {
	constexpr bool
	_M_has_value() const
	{ return this->_M_is_engaged(); }

	constexpr iterator_t<_Range>
	_M_get(const _Range&) const
	{
	  __glibcxx_assert(_M_has_value());
	  return **this;
	}

	constexpr void
	_M_set(const _Range&, const iterator_t<_Range>& __it)
	{
	  __glibcxx_assert(!_M_has_value());
	  std::construct_at(std::__addressof(this->_M_payload._M_payload),
			    in_place, __it);
	  this->_M_payload._M_engaged = true;
	}
      };

    template<random_access_range _Range>
      requires (sizeof(range_difference_t<_Range>)
		<= sizeof(iterator_t<_Range>))
      struct _CachedPosition<_Range>
      {
      private:
	range_difference_t<_Range> _M_offset = -1;

      public:
	_CachedPosition() = default;

	constexpr
	_CachedPosition(const _CachedPosition&) = default;

	constexpr
	_CachedPosition(_CachedPosition&& __other) noexcept
	{ *this = std::move(__other); }

	constexpr _CachedPosition&
	operator=(const _CachedPosition&) = default;

	constexpr _CachedPosition&
	operator=(_CachedPosition&& __other) noexcept
	{
	  // Propagate the cached offset, but invalidate the source.
	  _M_offset = __other._M_offset;
	  __other._M_offset = -1;
	  return *this;
	}

	constexpr bool
	_M_has_value() const
	{ return _M_offset >= 0; }

	constexpr iterator_t<_Range>
	_M_get(_Range& __r) const
	{
	  __glibcxx_assert(_M_has_value());
	  return ranges::begin(__r) + _M_offset;
	}

	constexpr void
	_M_set(_Range& __r, const iterator_t<_Range>& __it)
	{
	  __glibcxx_assert(!_M_has_value());
	  _M_offset = __it - ranges::begin(__r);
	}
      };
  } // namespace __detail

  namespace __detail
  {
    template<typename _Base>
      struct __filter_view_iter_cat
      { };

    template<forward_range _Base>
      struct __filter_view_iter_cat<_Base>
      {
      private:
	static auto
	_S_iter_cat()
	{
	  using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
	  if constexpr (derived_from<_Cat, bidirectional_iterator_tag>)
	    return bidirectional_iterator_tag{};
	  else if constexpr (derived_from<_Cat, forward_iterator_tag>)
	    return forward_iterator_tag{};
	  else
	    return _Cat{};
	}
      public:
	using iterator_category = decltype(_S_iter_cat());
      };
  } // namespace __detail

  template<input_range _Vp,
	   indirect_unary_predicate<iterator_t<_Vp>> _Pred>
    requires view<_Vp> && is_object_v<_Pred>
    class filter_view : public view_interface<filter_view<_Vp, _Pred>>
    {
    private:
      struct _Sentinel;

      struct _Iterator : __detail::__filter_view_iter_cat<_Vp>
      {
      private:
	static constexpr auto
	_S_iter_concept()
	{
	  if constexpr (bidirectional_range<_Vp>)
	    return bidirectional_iterator_tag{};
	  else if constexpr (forward_range<_Vp>)
	    return forward_iterator_tag{};
	  else
	    return input_iterator_tag{};
	}

	friend filter_view;

	using _Vp_iter = iterator_t<_Vp>;

	_Vp_iter _M_current = _Vp_iter();
	filter_view* _M_parent = nullptr;

      public:
	using iterator_concept = decltype(_S_iter_concept());
	// iterator_category defined in __filter_view_iter_cat
	using value_type = range_value_t<_Vp>;
	using difference_type = range_difference_t<_Vp>;

	_Iterator() requires default_initializable<_Vp_iter> = default;

	constexpr
	_Iterator(filter_view* __parent, _Vp_iter __current)
	  : _M_current(std::move(__current)),
	    _M_parent(__parent)
	{ }

	constexpr const _Vp_iter&
	base() const & noexcept
	{ return _M_current; }

	constexpr _Vp_iter
	base() &&
	{ return std::move(_M_current); }

	constexpr range_reference_t<_Vp>
	operator*() const
	{ return *_M_current; }

	constexpr _Vp_iter
	operator->() const
	  requires __detail::__has_arrow<_Vp_iter>
	    && copyable<_Vp_iter>
	{ return _M_current; }

	constexpr _Iterator&
	operator++()
	{
	  _M_current = ranges::find_if(std::move(++_M_current),
				       ranges::end(_M_parent->_M_base),
				       std::ref(*_M_parent->_M_pred));
	  return *this;
	}

	constexpr void
	operator++(int)
	{ ++*this; }

	constexpr _Iterator
	operator++(int) requires forward_range<_Vp>
	{
	  auto __tmp = *this;
	  ++*this;
	  return __tmp;
	}

	constexpr _Iterator&
	operator--() requires bidirectional_range<_Vp>
	{
	  do
	    --_M_current;
	  while (!std::__invoke(*_M_parent->_M_pred, *_M_current));
	  return *this;
	}

	constexpr _Iterator
	operator--(int) requires bidirectional_range<_Vp>
	{
	  auto __tmp = *this;
	  --*this;
	  return __tmp;
	}

	friend constexpr bool
	operator==(const _Iterator& __x, const _Iterator& __y)
	  requires equality_comparable<_Vp_iter>
	{ return __x._M_current == __y._M_current; }

	friend constexpr range_rvalue_reference_t<_Vp>
	iter_move(const _Iterator& __i)
	  noexcept(noexcept(ranges::iter_move(__i._M_current)))
	{ return ranges::iter_move(__i._M_current); }

	friend constexpr void
	iter_swap(const _Iterator& __x, const _Iterator& __y)
	  noexcept(noexcept(ranges::iter_swap(__x._M_current, __y._M_current)))
	  requires indirectly_swappable<_Vp_iter>
	{ ranges::iter_swap(__x._M_current, __y._M_current); }
      };

      struct _Sentinel
      {
      private:
	sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();

	constexpr bool
	__equal(const _Iterator& __i) const
	{ return __i._M_current == _M_end; }

      public:
	_Sentinel() = default;

	constexpr explicit
	_Sentinel(filter_view* __parent)
	  : _M_end(ranges::end(__parent->_M_base))
	{ }

	constexpr sentinel_t<_Vp>
	base() const
	{ return _M_end; }

	friend constexpr bool
	operator==(const _Iterator& __x, const _Sentinel& __y)
	{ return __y.__equal(__x); }
      };

      _Vp _M_base = _Vp();
      [[no_unique_address]] __detail::__box<_Pred> _M_pred;
      [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;

    public:
      filter_view() requires (default_initializable<_Vp>
			      && default_initializable<_Pred>)
	= default;

      constexpr
      filter_view(_Vp __base, _Pred __pred)
	: _M_base(std::move(__base)), _M_pred(std::move(__pred))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr const _Pred&
      pred() const
      { return *_M_pred; }

      constexpr _Iterator
      begin()
      {
	if (_M_cached_begin._M_has_value())
	  return {this, _M_cached_begin._M_get(_M_base)};

	__glibcxx_assert(_M_pred.has_value());
	auto __it = ranges::find_if(ranges::begin(_M_base),
				    ranges::end(_M_base),
				    std::ref(*_M_pred));
	_M_cached_begin._M_set(_M_base, __it);
	return {this, std::move(__it)};
      }

      constexpr auto
      end()
      {
	if constexpr (common_range<_Vp>)
	  return _Iterator{this, ranges::end(_M_base)};
	else
	  return _Sentinel{this};
      }
    };

  template<typename _Range, typename _Pred>
    filter_view(_Range&&, _Pred) -> filter_view<views::all_t<_Range>, _Pred>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pred>
	concept __can_filter_view
	  = requires { filter_view(std::declval<_Range>(), std::declval<_Pred>()); };
    } // namespace __detail

    struct _Filter : __adaptor::_RangeAdaptor<_Filter>
    {
      template<viewable_range _Range, typename _Pred>
	requires __detail::__can_filter_view<_Range, _Pred>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
	{
	  return filter_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
	}

      using _RangeAdaptor<_Filter>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _Filter filter;
  } // namespace views

  template<input_range _Vp, copy_constructible _Fp>
    requires view<_Vp> && is_object_v<_Fp>
      && regular_invocable<_Fp&, range_reference_t<_Vp>>
      && std::__detail::__can_reference<invoke_result_t<_Fp&,
							range_reference_t<_Vp>>>
    class transform_view : public view_interface<transform_view<_Vp, _Fp>>
    {
    private:
      template<bool _Const>
	using _Base = __detail::__maybe_const_t<_Const, _Vp>;

      template<bool _Const>
	struct __iter_cat
	{ };

      template<bool _Const>
	requires forward_range<_Base<_Const>>
	struct __iter_cat<_Const>
	{
	private:
	  static auto
	  _S_iter_cat()
	  {
	    using _Base = transform_view::_Base<_Const>;
	    using _Res = invoke_result_t<_Fp&, range_reference_t<_Base>>;
	    if constexpr (is_lvalue_reference_v<_Res>)
	      {
		using _Cat
		  = typename iterator_traits<iterator_t<_Base>>::iterator_category;
		if constexpr (derived_from<_Cat, contiguous_iterator_tag>)
		  return random_access_iterator_tag{};
		else
		  return _Cat{};
	      }
	    else
	      return input_iterator_tag{};
	  }
	public:
	  using iterator_category = decltype(_S_iter_cat());
	};

      template<bool _Const>
	struct _Sentinel;

      template<bool _Const>
	struct _Iterator : __iter_cat<_Const>
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
	  using _Base = transform_view::_Base<_Const>;

	  static auto
	  _S_iter_concept()
	  {
	    if constexpr (random_access_range<_Base>)
	      return random_access_iterator_tag{};
	    else if constexpr (bidirectional_range<_Base>)
	      return bidirectional_iterator_tag{};
	    else if constexpr (forward_range<_Base>)
	      return forward_iterator_tag{};
	    else
	      return input_iterator_tag{};
	  }

	  using _Base_iter = iterator_t<_Base>;

	  _Base_iter _M_current = _Base_iter();
	  _Parent* _M_parent = nullptr;

	public:
	  using iterator_concept = decltype(_S_iter_concept());
	  // iterator_category defined in __transform_view_iter_cat
	  using value_type
	    = remove_cvref_t<invoke_result_t<_Fp&, range_reference_t<_Base>>>;
	  using difference_type = range_difference_t<_Base>;

	  _Iterator() requires default_initializable<_Base_iter> = default;

	  constexpr
	  _Iterator(_Parent* __parent, _Base_iter __current)
	    : _M_current(std::move(__current)),
	      _M_parent(__parent)
	  { }

	  constexpr
	  _Iterator(_Iterator<!_Const> __i)
	    requires _Const
	      && convertible_to<iterator_t<_Vp>, _Base_iter>
	    : _M_current(std::move(__i._M_current)), _M_parent(__i._M_parent)
	  { }

	  constexpr const _Base_iter&
	  base() const & noexcept
	  { return _M_current; }

	  constexpr _Base_iter
	  base() &&
	  { return std::move(_M_current); }

	  constexpr decltype(auto)
	  operator*() const
	    noexcept(noexcept(std::__invoke(*_M_parent->_M_fun, *_M_current)))
	  { return std::__invoke(*_M_parent->_M_fun, *_M_current); }

	  constexpr _Iterator&
	  operator++()
	  {
	    ++_M_current;
	    return *this;
	  }

	  constexpr void
	  operator++(int)
	  { ++_M_current; }

	  constexpr _Iterator
	  operator++(int) requires forward_range<_Base>
	  {
	    auto __tmp = *this;
	    ++*this;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator--() requires bidirectional_range<_Base>
	  {
	    --_M_current;
	    return *this;
	  }

	  constexpr _Iterator
	  operator--(int) requires bidirectional_range<_Base>
	  {
	    auto __tmp = *this;
	    --*this;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator+=(difference_type __n) requires random_access_range<_Base>
	  {
	    _M_current += __n;
	    return *this;
	  }

	  constexpr _Iterator&
	  operator-=(difference_type __n) requires random_access_range<_Base>
	  {
	    _M_current -= __n;
	    return *this;
	  }

	  constexpr decltype(auto)
	  operator[](difference_type __n) const
	    requires random_access_range<_Base>
	  { return std::__invoke(*_M_parent->_M_fun, _M_current[__n]); }

	  friend constexpr bool
	  operator==(const _Iterator& __x, const _Iterator& __y)
	    requires equality_comparable<_Base_iter>
	  { return __x._M_current == __y._M_current; }

	  friend constexpr bool
	  operator<(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __x._M_current < __y._M_current; }

	  friend constexpr bool
	  operator>(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __y < __x; }

	  friend constexpr bool
	  operator<=(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return !(__y < __x); }

	  friend constexpr bool
	  operator>=(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return !(__x < __y); }

#ifdef __cpp_lib_three_way_comparison
	  friend constexpr auto
	  operator<=>(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	      && three_way_comparable<_Base_iter>
	  { return __x._M_current <=> __y._M_current; }
#endif

	  friend constexpr _Iterator
	  operator+(_Iterator __i, difference_type __n)
	    requires random_access_range<_Base>
	  { return {__i._M_parent, __i._M_current + __n}; }

	  friend constexpr _Iterator
	  operator+(difference_type __n, _Iterator __i)
	    requires random_access_range<_Base>
	  { return {__i._M_parent, __i._M_current + __n}; }

	  friend constexpr _Iterator
	  operator-(_Iterator __i, difference_type __n)
	    requires random_access_range<_Base>
	  { return {__i._M_parent, __i._M_current - __n}; }

	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3483. transform_view::iterator's difference is overconstrained
	  friend constexpr difference_type
	  operator-(const _Iterator& __x, const _Iterator& __y)
	    requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
	  { return __x._M_current - __y._M_current; }

	  friend constexpr decltype(auto)
	  iter_move(const _Iterator& __i) noexcept(noexcept(*__i))
	  {
	    if constexpr (is_lvalue_reference_v<decltype(*__i)>)
	      return std::move(*__i);
	    else
	      return *__i;
	  }

	  friend _Iterator<!_Const>;
	  template<bool> friend struct _Sentinel;
	};

      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, transform_view>;
	  using _Base = transform_view::_Base<_Const>;

	  template<bool _Const2>
	    constexpr auto
	    __distance_from(const _Iterator<_Const2>& __i) const
	    { return _M_end - __i._M_current; }

	  template<bool _Const2>
	    constexpr bool
	    __equal(const _Iterator<_Const2>& __i) const
	    { return __i._M_current == _M_end; }

	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(sentinel_t<_Base> __end)
	    : _M_end(__end)
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __i)
	    requires _Const
	      && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(std::move(__i._M_end))
	  { }

	  constexpr sentinel_t<_Base>
	  base() const
	  { return _M_end; }

	  template<bool _Const2>
	    requires sentinel_for<sentinel_t<_Base>,
		       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
	    friend constexpr bool
	    operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return __y.__equal(__x); }

	  template<bool _Const2,
		   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
	    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	    friend constexpr range_difference_t<_Base2>
	    operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return -__y.__distance_from(__x); }

	  template<bool _Const2,
		   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
	    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	    friend constexpr range_difference_t<_Base2>
	    operator-(const _Sentinel& __y, const _Iterator<_Const2>& __x)
	    { return __y.__distance_from(__x); }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
      [[no_unique_address]] __detail::__box<_Fp> _M_fun;

    public:
      transform_view() requires (default_initializable<_Vp>
				 && default_initializable<_Fp>)
	= default;

      constexpr
      transform_view(_Vp __base, _Fp __fun)
	: _M_base(std::move(__base)), _M_fun(std::move(__fun))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base ; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr _Iterator<false>
      begin()
      { return _Iterator<false>{this, ranges::begin(_M_base)}; }

      constexpr _Iterator<true>
      begin() const
	requires range<const _Vp>
	  && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
      { return _Iterator<true>{this, ranges::begin(_M_base)}; }

      constexpr _Sentinel<false>
      end()
      { return _Sentinel<false>{ranges::end(_M_base)}; }

      constexpr _Iterator<false>
      end() requires common_range<_Vp>
      { return _Iterator<false>{this, ranges::end(_M_base)}; }

      constexpr _Sentinel<true>
      end() const
	requires range<const _Vp>
	  && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
      { return _Sentinel<true>{ranges::end(_M_base)}; }

      constexpr _Iterator<true>
      end() const
	requires common_range<const _Vp>
	  && regular_invocable<const _Fp&, range_reference_t<const _Vp>>
      { return _Iterator<true>{this, ranges::end(_M_base)}; }

      constexpr auto
      size() requires sized_range<_Vp>
      { return ranges::size(_M_base); }

      constexpr auto
      size() const requires sized_range<const _Vp>
      { return ranges::size(_M_base); }
    };

  template<typename _Range, typename _Fp>
    transform_view(_Range&&, _Fp) -> transform_view<views::all_t<_Range>, _Fp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Fp>
	concept __can_transform_view
	  = requires { transform_view(std::declval<_Range>(), std::declval<_Fp>()); };
    } // namespace __detail

    struct _Transform : __adaptor::_RangeAdaptor<_Transform>
    {
      template<viewable_range _Range, typename _Fp>
	requires __detail::__can_transform_view<_Range, _Fp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Fp&& __f) const
	{
	  return transform_view(std::forward<_Range>(__r), std::forward<_Fp>(__f));
	}

      using _RangeAdaptor<_Transform>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _Transform transform;
  } // namespace views

  template<view _Vp>
    class take_view : public view_interface<take_view<_Vp>>
    {
    private:
      template<bool _Const>
	using _CI = counted_iterator<
	  iterator_t<__detail::__maybe_const_t<_Const, _Vp>>>;

      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Base = __detail::__maybe_const_t<_Const, _Vp>;
	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(sentinel_t<_Base> __end)
	    : _M_end(__end)
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __s)
	    requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(std::move(__s._M_end))
	  { }

	  constexpr sentinel_t<_Base>
	  base() const
	  { return _M_end; }

	  friend constexpr bool
	  operator==(const _CI<_Const>& __y, const _Sentinel& __x)
	  { return __y.count() == 0 || __y.base() == __x._M_end; }

	  template<bool _OtherConst = !_Const,
		   typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
	    requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	  friend constexpr bool
	  operator==(const _CI<_OtherConst>& __y, const _Sentinel& __x)
	  { return __y.count() == 0 || __y.base() == __x._M_end; }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
      range_difference_t<_Vp> _M_count = 0;

    public:
      take_view() requires default_initializable<_Vp> = default;

      constexpr
      take_view(_Vp base, range_difference_t<_Vp> __count)
	: _M_base(std::move(base)), _M_count(std::move(__count))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin() requires (!__detail::__simple_view<_Vp>)
      {
	if constexpr (sized_range<_Vp>)
	  {
	    if constexpr (random_access_range<_Vp>)
	      return ranges::begin(_M_base);
	    else
	      {
		auto __sz = size();
		return counted_iterator(ranges::begin(_M_base), __sz);
	      }
	  }
	else
	  return counted_iterator(ranges::begin(_M_base), _M_count);
      }

      constexpr auto
      begin() const requires range<const _Vp>
      {
	if constexpr (sized_range<const _Vp>)
	  {
	    if constexpr (random_access_range<const _Vp>)
	      return ranges::begin(_M_base);
	    else
	      {
		auto __sz = size();
		return counted_iterator(ranges::begin(_M_base), __sz);
	      }
	  }
	else
	  return counted_iterator(ranges::begin(_M_base), _M_count);
      }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp>)
      {
	if constexpr (sized_range<_Vp>)
	  {
	    if constexpr (random_access_range<_Vp>)
	      return ranges::begin(_M_base) + size();
	    else
	      return default_sentinel;
	  }
	else
	  return _Sentinel<false>{ranges::end(_M_base)};
      }

      constexpr auto
      end() const requires range<const _Vp>
      {
	if constexpr (sized_range<const _Vp>)
	  {
	    if constexpr (random_access_range<const _Vp>)
	      return ranges::begin(_M_base) + size();
	    else
	      return default_sentinel;
	  }
	else
	  return _Sentinel<true>{ranges::end(_M_base)};
      }

      constexpr auto
      size() requires sized_range<_Vp>
      {
	auto __n = ranges::size(_M_base);
	return std::min(__n, static_cast<decltype(__n)>(_M_count));
      }

      constexpr auto
      size() const requires sized_range<const _Vp>
      {
	auto __n = ranges::size(_M_base);
	return std::min(__n, static_cast<decltype(__n)>(_M_count));
      }
    };

  // _GLIBCXX_RESOLVE_LIB_DEFECTS
  // 3447. Deduction guides for take_view and drop_view have different
  // constraints
  template<typename _Range>
    take_view(_Range&&, range_difference_t<_Range>)
      -> take_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<take_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	inline constexpr bool __is_empty_view = false;

      template<typename _Tp>
	inline constexpr bool __is_empty_view<empty_view<_Tp>> = true;

      template<typename _Range>
	inline constexpr bool __is_basic_string_view = false;

      template<typename _CharT, typename _Traits>
	inline constexpr bool __is_basic_string_view<basic_string_view<_CharT, _Traits>>
	  = true;

      template<typename _Range>
	inline constexpr bool __is_subrange = false;

      template<typename _Iter, typename _Sent, subrange_kind _Kind>
	inline constexpr bool __is_subrange<subrange<_Iter, _Sent, _Kind>> = true;

      template<typename _Range>
	inline constexpr bool __is_iota_view = false;

      template<typename _Winc, typename _Bound>
	inline constexpr bool __is_iota_view<iota_view<_Winc, _Bound>> = true;

      template<typename _Range, typename _Dp>
	concept __can_take_view
	  = requires { take_view(std::declval<_Range>(), std::declval<_Dp>()); };
    } // namespace __detail

    struct _Take : __adaptor::_RangeAdaptor<_Take>
    {
      template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
	requires __detail::__can_take_view<_Range, _Dp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
	{
	  using _Tp = remove_cvref_t<_Range>;
	  if constexpr (__detail::__is_empty_view<_Tp>)
	    return _Tp();
	  else if constexpr (random_access_range<_Tp>
			     && sized_range<_Tp>
			     && (std::__detail::__is_span<_Tp>
				 || __detail::__is_basic_string_view<_Tp>
				 || __detail::__is_subrange<_Tp>
				 || __detail::__is_iota_view<_Tp>))
	    {
	      __n = std::min<_Dp>(ranges::distance(__r), __n);
	      auto __begin = ranges::begin(__r);
	      auto __end = __begin + __n;
	      if constexpr (std::__detail::__is_span<_Tp>)
		return span<typename _Tp::element_type>(__begin, __end);
	      else if constexpr (__detail::__is_basic_string_view<_Tp>)
		return _Tp(__begin, __end);
	      else if constexpr (__detail::__is_subrange<_Tp>)
		return subrange<iterator_t<_Tp>>(__begin, __end);
	      else
		return iota_view(*__begin, *__end);
	    }
	  else
	    return take_view(std::forward<_Range>(__r), __n);
	}

      using _RangeAdaptor<_Take>::operator();
      static constexpr int _S_arity = 2;
      // The count argument of views::take is not always simple -- it can be
      // e.g. a move-only class that's implicitly convertible to the difference
      // type.  But an integer-like count argument is surely simple.
      template<typename _Tp>
	static constexpr bool _S_has_simple_extra_args
	  = ranges::__detail::__is_integer_like<_Tp>;
    };

    inline constexpr _Take take;
  } // namespace views

  template<view _Vp, typename _Pred>
    requires input_range<_Vp> && is_object_v<_Pred>
      && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
    class take_while_view : public view_interface<take_while_view<_Vp, _Pred>>
    {
      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Base = __detail::__maybe_const_t<_Const, _Vp>;

	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();
	  const _Pred* _M_pred = nullptr;

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(sentinel_t<_Base> __end, const _Pred* __pred)
	    : _M_end(__end), _M_pred(__pred)
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __s)
	    requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(__s._M_end), _M_pred(__s._M_pred)
	  { }

	  constexpr sentinel_t<_Base>
	  base() const { return _M_end; }

	  friend constexpr bool
	  operator==(const iterator_t<_Base>& __x, const _Sentinel& __y)
	  { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }

	  template<bool _OtherConst = !_Const,
		   typename _Base2 = __detail::__maybe_const_t<_OtherConst, _Vp>>
	    requires sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	  friend constexpr bool
	  operator==(const iterator_t<_Base2>& __x, const _Sentinel& __y)
	  { return __y._M_end == __x || !std::__invoke(*__y._M_pred, *__x); }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
      [[no_unique_address]] __detail::__box<_Pred> _M_pred;

    public:
      take_while_view() requires (default_initializable<_Vp>
				  && default_initializable<_Pred>)
	= default;

      constexpr
      take_while_view(_Vp base, _Pred __pred)
	: _M_base(std::move(base)), _M_pred(std::move(__pred))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr const _Pred&
      pred() const
      { return *_M_pred; }

      constexpr auto
      begin() requires (!__detail::__simple_view<_Vp>)
      { return ranges::begin(_M_base); }

      constexpr auto
      begin() const requires range<const _Vp>
	&& indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
      { return ranges::begin(_M_base); }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp>)
      { return _Sentinel<false>(ranges::end(_M_base),
				std::__addressof(*_M_pred)); }

      constexpr auto
      end() const requires range<const _Vp>
	&& indirect_unary_predicate<const _Pred, iterator_t<const _Vp>>
      { return _Sentinel<true>(ranges::end(_M_base),
			       std::__addressof(*_M_pred)); }
    };

  template<typename _Range, typename _Pred>
    take_while_view(_Range&&, _Pred)
      -> take_while_view<views::all_t<_Range>, _Pred>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pred>
	concept __can_take_while_view
	  = requires { take_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
    } // namespace __detail

    struct _TakeWhile : __adaptor::_RangeAdaptor<_TakeWhile>
    {
      template<viewable_range _Range, typename _Pred>
	requires __detail::__can_take_while_view<_Range, _Pred>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
	{
	  return take_while_view(std::forward<_Range>(__r), std::forward<_Pred>(__p));
	}

      using _RangeAdaptor<_TakeWhile>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _TakeWhile take_while;
  } // namespace views

  template<view _Vp>
    class drop_view : public view_interface<drop_view<_Vp>>
    {
    private:
      _Vp _M_base = _Vp();
      range_difference_t<_Vp> _M_count = 0;

      // ranges::next(begin(base), count, end(base)) is O(1) if _Vp satisfies
      // both random_access_range and sized_range. Otherwise, cache its result.
      static constexpr bool _S_needs_cached_begin
	= !(random_access_range<const _Vp> && sized_range<const _Vp>);
      [[no_unique_address]]
	__detail::__maybe_present_t<_S_needs_cached_begin,
				    __detail::_CachedPosition<_Vp>>
				      _M_cached_begin;

    public:
      drop_view() requires default_initializable<_Vp> = default;

      constexpr
      drop_view(_Vp __base, range_difference_t<_Vp> __count)
	: _M_base(std::move(__base)), _M_count(__count)
      { __glibcxx_assert(__count >= 0); }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      // This overload is disabled for simple views with constant-time begin().
      constexpr auto
      begin()
	requires (!(__detail::__simple_view<_Vp>
		    && random_access_range<const _Vp>
		    && sized_range<const _Vp>))
      {
	if constexpr (_S_needs_cached_begin)
	  if (_M_cached_begin._M_has_value())
	    return _M_cached_begin._M_get(_M_base);

	auto __it = ranges::next(ranges::begin(_M_base),
				 _M_count, ranges::end(_M_base));
	if constexpr (_S_needs_cached_begin)
	  _M_cached_begin._M_set(_M_base, __it);
	return __it;
      }

      // _GLIBCXX_RESOLVE_LIB_DEFECTS
      // 3482. drop_view's const begin should additionally require sized_range
      constexpr auto
      begin() const
	requires random_access_range<const _Vp> && sized_range<const _Vp>
      {
	return ranges::next(ranges::begin(_M_base), _M_count,
			    ranges::end(_M_base));
      }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp>)
      { return ranges::end(_M_base); }

      constexpr auto
      end() const requires range<const _Vp>
      { return ranges::end(_M_base); }

      constexpr auto
      size() requires sized_range<_Vp>
      {
	const auto __s = ranges::size(_M_base);
	const auto __c = static_cast<decltype(__s)>(_M_count);
	return __s < __c ? 0 : __s - __c;
      }

      constexpr auto
      size() const requires sized_range<const _Vp>
      {
	const auto __s = ranges::size(_M_base);
	const auto __c = static_cast<decltype(__s)>(_M_count);
	return __s < __c ? 0 : __s - __c;
      }
    };

  template<typename _Range>
    drop_view(_Range&&, range_difference_t<_Range>)
      -> drop_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<drop_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Dp>
	concept __can_drop_view
	  = requires { drop_view(std::declval<_Range>(), std::declval<_Dp>()); };
    } // namespace __detail

    struct _Drop : __adaptor::_RangeAdaptor<_Drop>
    {
      template<viewable_range _Range, typename _Dp = range_difference_t<_Range>>
	requires __detail::__can_drop_view<_Range, _Dp>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, type_identity_t<_Dp> __n) const
	{
	  using _Tp = remove_cvref_t<_Range>;
	  if constexpr (__detail::__is_empty_view<_Tp>)
	    return _Tp();
	  else if constexpr (random_access_range<_Tp>
			     && sized_range<_Tp>
			     && (std::__detail::__is_span<_Tp>
				 || __detail::__is_basic_string_view<_Tp>
				 || __detail::__is_iota_view<_Tp>
				 || __detail::__is_subrange<_Tp>))
	    {
	      __n = std::min<_Dp>(ranges::distance(__r), __n);
	      auto __begin = ranges::begin(__r) + __n;
	      auto __end = ranges::end(__r);
	      if constexpr (std::__detail::__is_span<_Tp>)
		return span<typename _Tp::element_type>(__begin, __end);
	      else if constexpr (__detail::__is_subrange<_Tp>)
		{
		  if constexpr (_Tp::_S_store_size)
		    {
		      using ranges::__detail::__to_unsigned_like;
		      auto __m = ranges::distance(__r) - __n;
		      return _Tp(__begin, __end, __to_unsigned_like(__m));
		    }
		  else
		    return _Tp(__begin, __end);
		}
	      else
		return _Tp(__begin, __end);
	    }
	  else
	    return drop_view(std::forward<_Range>(__r), __n);
	}

      using _RangeAdaptor<_Drop>::operator();
      static constexpr int _S_arity = 2;
      template<typename _Tp>
	static constexpr bool _S_has_simple_extra_args
	  = _Take::_S_has_simple_extra_args<_Tp>;
    };

    inline constexpr _Drop drop;
  } // namespace views

  template<view _Vp, typename _Pred>
    requires input_range<_Vp> && is_object_v<_Pred>
      && indirect_unary_predicate<const _Pred, iterator_t<_Vp>>
    class drop_while_view : public view_interface<drop_while_view<_Vp, _Pred>>
    {
    private:
      _Vp _M_base = _Vp();
      [[no_unique_address]] __detail::__box<_Pred> _M_pred;
      [[no_unique_address]] __detail::_CachedPosition<_Vp> _M_cached_begin;

    public:
      drop_while_view() requires (default_initializable<_Vp>
				  && default_initializable<_Pred>)
	= default;

      constexpr
      drop_while_view(_Vp __base, _Pred __pred)
	: _M_base(std::move(__base)), _M_pred(std::move(__pred))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr const _Pred&
      pred() const
      { return *_M_pred; }

      constexpr auto
      begin()
      {
	if (_M_cached_begin._M_has_value())
	  return _M_cached_begin._M_get(_M_base);

	__glibcxx_assert(_M_pred.has_value());
	auto __it = ranges::find_if_not(ranges::begin(_M_base),
					ranges::end(_M_base),
					std::cref(*_M_pred));
	_M_cached_begin._M_set(_M_base, __it);
	return __it;
      }

      constexpr auto
      end()
      { return ranges::end(_M_base); }
    };

  template<typename _Range, typename _Pred>
    drop_while_view(_Range&&, _Pred)
      -> drop_while_view<views::all_t<_Range>, _Pred>;

  template<typename _Tp, typename _Pred>
    inline constexpr bool enable_borrowed_range<drop_while_view<_Tp, _Pred>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pred>
	concept __can_drop_while_view
	  = requires { drop_while_view(std::declval<_Range>(), std::declval<_Pred>()); };
    } // namespace __detail

    struct _DropWhile : __adaptor::_RangeAdaptor<_DropWhile>
    {
      template<viewable_range _Range, typename _Pred>
	requires __detail::__can_drop_while_view<_Range, _Pred>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pred&& __p) const
	{
	  return drop_while_view(std::forward<_Range>(__r),
				 std::forward<_Pred>(__p));
	}

      using _RangeAdaptor<_DropWhile>::operator();
      static constexpr int _S_arity = 2;
      static constexpr bool _S_has_simple_extra_args = true;
    };

    inline constexpr _DropWhile drop_while;
  } // namespace views

  template<input_range _Vp>
    requires view<_Vp> && input_range<range_reference_t<_Vp>>
    class join_view : public view_interface<join_view<_Vp>>
    {
    private:
      using _InnerRange = range_reference_t<_Vp>;

      template<bool _Const>
	using _Base = __detail::__maybe_const_t<_Const, _Vp>;

      template<bool _Const>
	using _Outer_iter = iterator_t<_Base<_Const>>;

      template<bool _Const>
	using _Inner_iter = iterator_t<range_reference_t<_Base<_Const>>>;

      template<bool _Const>
	static constexpr bool _S_ref_is_glvalue
	  = is_reference_v<range_reference_t<_Base<_Const>>>;

      template<bool _Const>
	struct __iter_cat
	{ };

      template<bool _Const>
	requires _S_ref_is_glvalue<_Const>
	  && forward_range<_Base<_Const>>
	  && forward_range<range_reference_t<_Base<_Const>>>
	struct __iter_cat<_Const>
	{
	private:
	  static constexpr auto
	  _S_iter_cat()
	  {
	    using _Outer_iter = join_view::_Outer_iter<_Const>;
	    using _Inner_iter = join_view::_Inner_iter<_Const>;
	    using _OuterCat = typename iterator_traits<_Outer_iter>::iterator_category;
	    using _InnerCat = typename iterator_traits<_Inner_iter>::iterator_category;
	    if constexpr (derived_from<_OuterCat, bidirectional_iterator_tag>
			  && derived_from<_InnerCat, bidirectional_iterator_tag>
			  && common_range<range_reference_t<_Base<_Const>>>)
	      return bidirectional_iterator_tag{};
	    else if constexpr (derived_from<_OuterCat, forward_iterator_tag>
			       && derived_from<_InnerCat, forward_iterator_tag>)
	      return forward_iterator_tag{};
	    else
	      return input_iterator_tag{};
	  }
	public:
	  using iterator_category = decltype(_S_iter_cat());
	};

      template<bool _Const>
	struct _Sentinel;

      template<bool _Const>
	struct _Iterator : __iter_cat<_Const>
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, join_view>;
	  using _Base = join_view::_Base<_Const>;

	  static constexpr bool _S_ref_is_glvalue
	    = join_view::_S_ref_is_glvalue<_Const>;

	  constexpr void
	  _M_satisfy()
	  {
	    auto __update_inner = [this] (const iterator_t<_Base>& __x) -> auto&& {
	      if constexpr (_S_ref_is_glvalue)
		return *__x;
	      else
		return _M_parent->_M_inner._M_emplace_deref(__x);
	    };

	    for (; _M_outer != ranges::end(_M_parent->_M_base); ++_M_outer)
	      {
		auto&& __inner = __update_inner(_M_outer);
		_M_inner = ranges::begin(__inner);
		if (_M_inner != ranges::end(__inner))
		  return;
	      }

	    if constexpr (_S_ref_is_glvalue)
	      _M_inner = _Inner_iter();
	  }

	  static constexpr auto
	  _S_iter_concept()
	  {
	    if constexpr (_S_ref_is_glvalue
			  && bidirectional_range<_Base>
			  && bidirectional_range<range_reference_t<_Base>>
			  && common_range<range_reference_t<_Base>>)
	      return bidirectional_iterator_tag{};
	    else if constexpr (_S_ref_is_glvalue
			       && forward_range<_Base>
			       && forward_range<range_reference_t<_Base>>)
	      return forward_iterator_tag{};
	    else
	      return input_iterator_tag{};
	  }

	  using _Outer_iter = join_view::_Outer_iter<_Const>;
	  using _Inner_iter = join_view::_Inner_iter<_Const>;

	  _Outer_iter _M_outer = _Outer_iter();
	  _Inner_iter _M_inner = _Inner_iter();
	  _Parent* _M_parent = nullptr;

	public:
	  using iterator_concept = decltype(_S_iter_concept());
	  // iterator_category defined in __join_view_iter_cat
	  using value_type = range_value_t<range_reference_t<_Base>>;
	  using difference_type
	    = common_type_t<range_difference_t<_Base>,
			    range_difference_t<range_reference_t<_Base>>>;

	  _Iterator() requires (default_initializable<_Outer_iter>
				&& default_initializable<_Inner_iter>)
	    = default;

	  constexpr
	  _Iterator(_Parent* __parent, _Outer_iter __outer)
	    : _M_outer(std::move(__outer)),
	      _M_parent(__parent)
	  { _M_satisfy(); }

	  constexpr
	  _Iterator(_Iterator<!_Const> __i)
	    requires _Const
	      && convertible_to<iterator_t<_Vp>, _Outer_iter>
	      && convertible_to<iterator_t<_InnerRange>, _Inner_iter>
	    : _M_outer(std::move(__i._M_outer)), _M_inner(std::move(__i._M_inner)),
	      _M_parent(__i._M_parent)
	  { }

	  constexpr decltype(auto)
	  operator*() const
	  { return *_M_inner; }

	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3500. join_view::iterator::operator->() is bogus
	  constexpr _Inner_iter
	  operator->() const
	    requires __detail::__has_arrow<_Inner_iter>
	      && copyable<_Inner_iter>
	  { return _M_inner; }

	  constexpr _Iterator&
	  operator++()
	  {
	    auto&& __inner_range = [this] () -> auto&& {
	      if constexpr (_S_ref_is_glvalue)
		return *_M_outer;
	      else
		return *_M_parent->_M_inner;
	    }();
	    if (++_M_inner == ranges::end(__inner_range))
	      {
		++_M_outer;
		_M_satisfy();
	      }
	    return *this;
	  }

	  constexpr void
	  operator++(int)
	  { ++*this; }

	  constexpr _Iterator
	  operator++(int)
	    requires _S_ref_is_glvalue && forward_range<_Base>
	      && forward_range<range_reference_t<_Base>>
	  {
	    auto __tmp = *this;
	    ++*this;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator--()
	    requires _S_ref_is_glvalue && bidirectional_range<_Base>
	      && bidirectional_range<range_reference_t<_Base>>
	      && common_range<range_reference_t<_Base>>
	  {
	    if (_M_outer == ranges::end(_M_parent->_M_base))
	      _M_inner = ranges::end(*--_M_outer);
	    while (_M_inner == ranges::begin(*_M_outer))
	      _M_inner = ranges::end(*--_M_outer);
	    --_M_inner;
	    return *this;
	  }

	  constexpr _Iterator
	  operator--(int)
	    requires _S_ref_is_glvalue && bidirectional_range<_Base>
	      && bidirectional_range<range_reference_t<_Base>>
	      && common_range<range_reference_t<_Base>>
	  {
	    auto __tmp = *this;
	    --*this;
	    return __tmp;
	  }

	  friend constexpr bool
	  operator==(const _Iterator& __x, const _Iterator& __y)
	    requires _S_ref_is_glvalue
	      && equality_comparable<_Outer_iter>
	      && equality_comparable<_Inner_iter>
	  {
	    return (__x._M_outer == __y._M_outer
		    && __x._M_inner == __y._M_inner);
	  }

	  friend constexpr decltype(auto)
	  iter_move(const _Iterator& __i)
	  noexcept(noexcept(ranges::iter_move(__i._M_inner)))
	  { return ranges::iter_move(__i._M_inner); }

	  friend constexpr void
	  iter_swap(const _Iterator& __x, const _Iterator& __y)
	    noexcept(noexcept(ranges::iter_swap(__x._M_inner, __y._M_inner)))
	    requires indirectly_swappable<_Inner_iter>
	  { return ranges::iter_swap(__x._M_inner, __y._M_inner); }

	  friend _Iterator<!_Const>;
	  template<bool> friend struct _Sentinel;
	};

      template<bool _Const>
	struct _Sentinel
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, join_view>;
	  using _Base = join_view::_Base<_Const>;

	  template<bool _Const2>
	    constexpr bool
	    __equal(const _Iterator<_Const2>& __i) const
	    { return __i._M_outer == _M_end; }

	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(_Parent* __parent)
	    : _M_end(ranges::end(__parent->_M_base))
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __s)
	    requires _Const && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(std::move(__s._M_end))
	  { }

	  template<bool _Const2>
	    requires sentinel_for<sentinel_t<_Base>,
		       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
	    friend constexpr bool
	    operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return __y.__equal(__x); }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
      [[no_unique_address]]
	__detail::__non_propagating_cache<remove_cv_t<_InnerRange>> _M_inner;

    public:
      join_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      join_view(_Vp __base)
	: _M_base(std::move(__base))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin()
      {
	constexpr bool __use_const
	  = (__detail::__simple_view<_Vp>
	     && is_reference_v<range_reference_t<_Vp>>);
	return _Iterator<__use_const>{this, ranges::begin(_M_base)};
      }

      constexpr auto
      begin() const
	requires input_range<const _Vp>
	  && is_reference_v<range_reference_t<const _Vp>>
      {
	return _Iterator<true>{this, ranges::begin(_M_base)};
      }

      constexpr auto
      end()
      {
	if constexpr (forward_range<_Vp> && is_reference_v<_InnerRange>
		      && forward_range<_InnerRange>
		      && common_range<_Vp> && common_range<_InnerRange>)
	  return _Iterator<__detail::__simple_view<_Vp>>{this,
							 ranges::end(_M_base)};
	else
	  return _Sentinel<__detail::__simple_view<_Vp>>{this};
      }

      constexpr auto
      end() const
	requires input_range<const _Vp>
	  && is_reference_v<range_reference_t<const _Vp>>
      {
	if constexpr (forward_range<const _Vp>
		      && is_reference_v<range_reference_t<const _Vp>>
		      && forward_range<range_reference_t<const _Vp>>
		      && common_range<const _Vp>
		      && common_range<range_reference_t<const _Vp>>)
	  return _Iterator<true>{this, ranges::end(_M_base)};
	else
	  return _Sentinel<true>{this};
      }
    };

  template<typename _Range>
    explicit join_view(_Range&&) -> join_view<views::all_t<_Range>>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	concept __can_join_view
	  = requires { join_view<all_t<_Range>>{std::declval<_Range>()}; };
    } // namespace __detail

    struct _Join : __adaptor::_RangeAdaptorClosure
    {
      template<viewable_range _Range>
	requires __detail::__can_join_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{
	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3474. Nesting join_views is broken because of CTAD
	  return join_view<all_t<_Range>>{std::forward<_Range>(__r)};
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _Join join;
  } // namespace views

  namespace __detail
  {
    template<auto>
      struct __require_constant;

    template<typename _Range>
      concept __tiny_range = sized_range<_Range>
	&& requires
	   { typename __require_constant<remove_reference_t<_Range>::size()>; }
	&& (remove_reference_t<_Range>::size() <= 1);

    template<typename _Base>
      struct __lazy_split_view_outer_iter_cat
      { };

    template<forward_range _Base>
      struct __lazy_split_view_outer_iter_cat<_Base>
      { using iterator_category = input_iterator_tag; };

    template<typename _Base>
      struct __lazy_split_view_inner_iter_cat
      { };

    template<forward_range _Base>
      struct __lazy_split_view_inner_iter_cat<_Base>
      {
      private:
	static constexpr auto
	_S_iter_cat()
	{
	  using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
	  if constexpr (derived_from<_Cat, forward_iterator_tag>)
	    return forward_iterator_tag{};
	  else
	    return _Cat{};
	}
      public:
	using iterator_category = decltype(_S_iter_cat());
      };
  }

  template<input_range _Vp, forward_range _Pattern>
    requires view<_Vp> && view<_Pattern>
      && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
			       ranges::equal_to>
      && (forward_range<_Vp> || __detail::__tiny_range<_Pattern>)
    class lazy_split_view : public view_interface<lazy_split_view<_Vp, _Pattern>>
    {
    private:
      template<bool _Const>
	using _Base = __detail::__maybe_const_t<_Const, _Vp>;

      template<bool _Const>
	struct _InnerIter;

      template<bool _Const>
	struct _OuterIter
	  : __detail::__lazy_split_view_outer_iter_cat<_Base<_Const>>
	{
	private:
	  using _Parent = __detail::__maybe_const_t<_Const, lazy_split_view>;
	  using _Base = lazy_split_view::_Base<_Const>;

	  constexpr bool
	  __at_end() const
	  { return __current() == ranges::end(_M_parent->_M_base) && !_M_trailing_empty; }

	  // [range.lazy.split.outer] p1
	  //  Many of the following specifications refer to the notional member
	  //  current of outer-iterator.  current is equivalent to current_ if
	  //  V models forward_range, and parent_->current_ otherwise.
	  constexpr auto&
	  __current() noexcept
	  {
	    if constexpr (forward_range<_Vp>)
	      return _M_current;
	    else
	      return *_M_parent->_M_current;
	  }

	  constexpr auto&
	  __current() const noexcept
	  {
	    if constexpr (forward_range<_Vp>)
	      return _M_current;
	    else
	      return *_M_parent->_M_current;
	  }

	  _Parent* _M_parent = nullptr;

	  // XXX: _M_current is present only if "V models forward_range"
	  [[no_unique_address]]
	    __detail::__maybe_present_t<forward_range<_Vp>,
					iterator_t<_Base>> _M_current;
	  bool _M_trailing_empty = false;

	public:
	  using iterator_concept = __conditional_t<forward_range<_Base>,
						   forward_iterator_tag,
						   input_iterator_tag>;
	  // iterator_category defined in __lazy_split_view_outer_iter_cat
	  using difference_type = range_difference_t<_Base>;

	  struct value_type : view_interface<value_type>
	  {
	  private:
	    _OuterIter _M_i = _OuterIter();

	  public:
	    value_type() = default;

	    constexpr explicit
	    value_type(_OuterIter __i)
	      : _M_i(std::move(__i))
	    { }

	    constexpr _InnerIter<_Const>
	    begin() const
	    { return _InnerIter<_Const>{_M_i}; }

	    constexpr default_sentinel_t
	    end() const noexcept
	    { return default_sentinel; }
	  };

	  _OuterIter() = default;

	  constexpr explicit
	  _OuterIter(_Parent* __parent) requires (!forward_range<_Base>)
	    : _M_parent(__parent)
	  { }

	  constexpr
	  _OuterIter(_Parent* __parent, iterator_t<_Base> __current)
	    requires forward_range<_Base>
	    : _M_parent(__parent),
	      _M_current(std::move(__current))
	  { }

	  constexpr
	  _OuterIter(_OuterIter<!_Const> __i)
	    requires _Const
	      && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
	    : _M_parent(__i._M_parent), _M_current(std::move(__i._M_current))
	  { }

	  constexpr value_type
	  operator*() const
	  { return value_type{*this}; }

	  constexpr _OuterIter&
	  operator++()
	  {
	    // _GLIBCXX_RESOLVE_LIB_DEFECTS
	    // 3505. lazy_split_view::outer-iterator::operator++ misspecified
	    const auto __end = ranges::end(_M_parent->_M_base);
	    if (__current() == __end)
	      {
		_M_trailing_empty = false;
		return *this;
	      }
	    const auto [__pbegin, __pend] = subrange{_M_parent->_M_pattern};
	    if (__pbegin == __pend)
	      ++__current();
	    else if constexpr (__detail::__tiny_range<_Pattern>)
	      {
		__current() = ranges::find(std::move(__current()), __end,
					   *__pbegin);
		if (__current() != __end)
		  {
		    ++__current();
		    if (__current() == __end)
		      _M_trailing_empty = true;
		  }
	      }
	    else
	      do
		{
		  auto [__b, __p]
		    = ranges::mismatch(__current(), __end, __pbegin, __pend);
		  if (__p == __pend)
		    {
		      __current() = __b;
		      if (__current() == __end)
			_M_trailing_empty = true;
		      break;
		    }
		} while (++__current() != __end);
	    return *this;
	  }

	  constexpr decltype(auto)
	  operator++(int)
	  {
	    if constexpr (forward_range<_Base>)
	      {
		auto __tmp = *this;
		++*this;
		return __tmp;
	      }
	    else
	      ++*this;
	  }

	  friend constexpr bool
	  operator==(const _OuterIter& __x, const _OuterIter& __y)
	    requires forward_range<_Base>
	  {
	    return __x._M_current == __y._M_current
	      && __x._M_trailing_empty == __y._M_trailing_empty;
	  }

	  friend constexpr bool
	  operator==(const _OuterIter& __x, default_sentinel_t)
	  { return __x.__at_end(); };

	  friend _OuterIter<!_Const>;
	  friend _InnerIter<_Const>;
	};

      template<bool _Const>
	struct _InnerIter
	  : __detail::__lazy_split_view_inner_iter_cat<_Base<_Const>>
	{
	private:
	  using _Base = lazy_split_view::_Base<_Const>;

	  constexpr bool
	  __at_end() const
	  {
	    auto [__pcur, __pend] = subrange{_M_i._M_parent->_M_pattern};
	    auto __end = ranges::end(_M_i._M_parent->_M_base);
	    if constexpr (__detail::__tiny_range<_Pattern>)
	      {
		const auto& __cur = _M_i_current();
		if (__cur == __end)
		  return true;
		if (__pcur == __pend)
		  return _M_incremented;
		return *__cur == *__pcur;
	      }
	    else
	      {
		auto __cur = _M_i_current();
		if (__cur == __end)
		  return true;
		if (__pcur == __pend)
		  return _M_incremented;
		do
		  {
		    if (*__cur != *__pcur)
		      return false;
		    if (++__pcur == __pend)
		      return true;
		  } while (++__cur != __end);
		return false;
	      }
	  }

	  constexpr auto&
	  _M_i_current() noexcept
	  { return _M_i.__current(); }

	  constexpr auto&
	  _M_i_current() const noexcept
	  { return _M_i.__current(); }

	  _OuterIter<_Const> _M_i = _OuterIter<_Const>();
	  bool _M_incremented = false;

	public:
	  using iterator_concept
	    = typename _OuterIter<_Const>::iterator_concept;
	  // iterator_category defined in __lazy_split_view_inner_iter_cat
	  using value_type = range_value_t<_Base>;
	  using difference_type = range_difference_t<_Base>;

	  _InnerIter() = default;

	  constexpr explicit
	  _InnerIter(_OuterIter<_Const> __i)
	    : _M_i(std::move(__i))
	  { }

	  constexpr const iterator_t<_Base>&
	  base() const& noexcept
	  { return _M_i_current(); }

	  constexpr iterator_t<_Base>
	  base() && requires forward_range<_Vp>
	  { return std::move(_M_i_current()); }

	  constexpr decltype(auto)
	  operator*() const
	  { return *_M_i_current(); }

	  constexpr _InnerIter&
	  operator++()
	  {
	    _M_incremented = true;
	    if constexpr (!forward_range<_Base>)
	      if constexpr (_Pattern::size() == 0)
		return *this;
	    ++_M_i_current();
	    return *this;
	  }

	  constexpr decltype(auto)
	  operator++(int)
	  {
	    if constexpr (forward_range<_Base>)
	      {
		auto __tmp = *this;
		++*this;
		return __tmp;
	      }
	    else
	      ++*this;
	  }

	  friend constexpr bool
	  operator==(const _InnerIter& __x, const _InnerIter& __y)
	    requires forward_range<_Base>
	  { return __x._M_i == __y._M_i; }

	  friend constexpr bool
	  operator==(const _InnerIter& __x, default_sentinel_t)
	  { return __x.__at_end(); }

	  friend constexpr decltype(auto)
	  iter_move(const _InnerIter& __i)
	    noexcept(noexcept(ranges::iter_move(__i._M_i_current())))
	  { return ranges::iter_move(__i._M_i_current()); }

	  friend constexpr void
	  iter_swap(const _InnerIter& __x, const _InnerIter& __y)
	    noexcept(noexcept(ranges::iter_swap(__x._M_i_current(),
						__y._M_i_current())))
	    requires indirectly_swappable<iterator_t<_Base>>
	  { ranges::iter_swap(__x._M_i_current(), __y._M_i_current()); }
	};

      _Vp _M_base = _Vp();
      _Pattern _M_pattern = _Pattern();
      // XXX: _M_current is "present only if !forward_range<V>"
      [[no_unique_address]]
	__detail::__maybe_present_t<!forward_range<_Vp>,
	  __detail::__non_propagating_cache<iterator_t<_Vp>>> _M_current;


    public:
      lazy_split_view() requires (default_initializable<_Vp>
				  && default_initializable<_Pattern>)
	= default;

      constexpr
      lazy_split_view(_Vp __base, _Pattern __pattern)
	: _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
      { }

      template<input_range _Range>
	requires constructible_from<_Vp, views::all_t<_Range>>
	  && constructible_from<_Pattern, single_view<range_value_t<_Range>>>
	constexpr
	lazy_split_view(_Range&& __r, range_value_t<_Range> __e)
	  : _M_base(views::all(std::forward<_Range>(__r))),
	    _M_pattern(views::single(std::move(__e)))
	{ }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin()
      {
	if constexpr (forward_range<_Vp>)
	  {
	    constexpr bool __simple
	      = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
	    return _OuterIter<__simple>{this, ranges::begin(_M_base)};
	  }
	else
	  {
	    _M_current = ranges::begin(_M_base);
	    return _OuterIter<false>{this};
	  }
      }

      constexpr auto
      begin() const requires forward_range<_Vp> && forward_range<const _Vp>
      {
	return _OuterIter<true>{this, ranges::begin(_M_base)};
      }

      constexpr auto
      end() requires forward_range<_Vp> && common_range<_Vp>
      {
	constexpr bool __simple
	  = __detail::__simple_view<_Vp> && __detail::__simple_view<_Pattern>;
	return _OuterIter<__simple>{this, ranges::end(_M_base)};
      }

      constexpr auto
      end() const
      {
	if constexpr (forward_range<_Vp>
		      && forward_range<const _Vp>
		      && common_range<const _Vp>)
	  return _OuterIter<true>{this, ranges::end(_M_base)};
	else
	  return default_sentinel;
      }
    };

  template<typename _Range, typename _Pattern>
    lazy_split_view(_Range&&, _Pattern&&)
      -> lazy_split_view<views::all_t<_Range>, views::all_t<_Pattern>>;

  template<input_range _Range>
    lazy_split_view(_Range&&, range_value_t<_Range>)
      -> lazy_split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pattern>
	concept __can_lazy_split_view
	  = requires { lazy_split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
    } // namespace __detail

    struct _LazySplit : __adaptor::_RangeAdaptor<_LazySplit>
    {
      template<viewable_range _Range, typename _Pattern>
	requires __detail::__can_lazy_split_view<_Range, _Pattern>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
	{
	  return lazy_split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
	}

      using _RangeAdaptor<_LazySplit>::operator();
      static constexpr int _S_arity = 2;
      // The pattern argument of views::lazy_split is not always simple -- it can be
      // a non-view range, the value category of which affects whether the call
      // is well-formed.  But a scalar or a view pattern argument is surely
      // simple.
      template<typename _Pattern>
	static constexpr bool _S_has_simple_extra_args
	  = is_scalar_v<_Pattern> || (view<_Pattern>
				      && copy_constructible<_Pattern>);
    };

    inline constexpr _LazySplit lazy_split;
  } // namespace views

  template<forward_range _Vp, forward_range _Pattern>
    requires view<_Vp> && view<_Pattern>
      && indirectly_comparable<iterator_t<_Vp>, iterator_t<_Pattern>,
			       ranges::equal_to>
  class split_view : public view_interface<split_view<_Vp, _Pattern>>
  {
  private:
    _Vp _M_base = _Vp();
    _Pattern _M_pattern = _Pattern();
    __detail::__non_propagating_cache<subrange<iterator_t<_Vp>>> _M_cached_begin;

    struct _Iterator;
    struct _Sentinel;

  public:
    split_view() requires (default_initializable<_Vp>
			   && default_initializable<_Pattern>)
      = default;

    constexpr
    split_view(_Vp __base, _Pattern __pattern)
      : _M_base(std::move(__base)), _M_pattern(std::move(__pattern))
    { }

    template<forward_range _Range>
      requires constructible_from<_Vp, views::all_t<_Range>>
	&& constructible_from<_Pattern, single_view<range_value_t<_Range>>>
    constexpr
    split_view(_Range&& __r, range_value_t<_Range> __e)
      : _M_base(views::all(std::forward<_Range>(__r))),
	_M_pattern(views::single(std::move(__e)))
    { }

    constexpr _Vp
    base() const& requires copy_constructible<_Vp>
    { return _M_base; }

    constexpr _Vp
    base() &&
    { return std::move(_M_base); }

    constexpr _Iterator
    begin()
    {
      if (!_M_cached_begin)
	_M_cached_begin = _M_find_next(ranges::begin(_M_base));
      return {this, ranges::begin(_M_base), *_M_cached_begin};
    }

    constexpr auto
    end()
    {
      if constexpr (common_range<_Vp>)
	return _Iterator{this, ranges::end(_M_base), {}};
      else
	return _Sentinel{this};
    }

    constexpr subrange<iterator_t<_Vp>>
    _M_find_next(iterator_t<_Vp> __it)
    {
      auto [__b, __e] = ranges::search(subrange(__it, ranges::end(_M_base)), _M_pattern);
      if (__b != ranges::end(_M_base) && ranges::empty(_M_pattern))
	{
	  ++__b;
	  ++__e;
	}
      return {__b, __e};
    }

  private:
    struct _Iterator
    {
    private:
      split_view* _M_parent = nullptr;
      iterator_t<_Vp> _M_cur = iterator_t<_Vp>();
      subrange<iterator_t<_Vp>> _M_next = subrange<iterator_t<_Vp>>();
      bool _M_trailing_empty = false;

      friend struct _Sentinel;

    public:
      using iterator_concept = forward_iterator_tag;
      using iterator_category = input_iterator_tag;
      using value_type = subrange<iterator_t<_Vp>>;
      using difference_type = range_difference_t<_Vp>;

      _Iterator() = default;

      constexpr
      _Iterator(split_view* __parent,
		iterator_t<_Vp> __current,
		subrange<iterator_t<_Vp>> __next)
	: _M_parent(__parent),
	  _M_cur(std::move(__current)),
	  _M_next(std::move(__next))
      { }

      constexpr iterator_t<_Vp>
      base() const
      { return _M_cur; }

      constexpr value_type
      operator*() const
      { return {_M_cur, _M_next.begin()}; }

      constexpr _Iterator&
      operator++()
      {
	_M_cur = _M_next.begin();
	if (_M_cur != ranges::end(_M_parent->_M_base))
	  {
	    _M_cur = _M_next.end();
	    if (_M_cur == ranges::end(_M_parent->_M_base))
	      {
		_M_trailing_empty = true;
		_M_next = {_M_cur, _M_cur};
	      }
	    else
	      _M_next = _M_parent->_M_find_next(_M_cur);
	  }
	else
	  _M_trailing_empty = false;
	return *this;
      }

      constexpr _Iterator
      operator++(int)
      {
	auto __tmp = *this;
	++*this;
	return __tmp;
      }

      friend constexpr bool
      operator==(const _Iterator& __x, const _Iterator& __y)
      {
	return __x._M_cur == __y._M_cur
	  && __x._M_trailing_empty == __y._M_trailing_empty;
      }
    };

    struct _Sentinel
    {
    private:
      sentinel_t<_Vp> _M_end = sentinel_t<_Vp>();

      constexpr bool
      _M_equal(const _Iterator& __x) const
      { return __x._M_cur == _M_end && !__x._M_trailing_empty; }

    public:
      _Sentinel() = default;

      constexpr explicit
      _Sentinel(split_view* __parent)
	: _M_end(ranges::end(__parent->_M_base))
      { }

      friend constexpr bool
      operator==(const _Iterator& __x, const _Sentinel& __y)
      { return __y._M_equal(__x); }
    };
  };

  template<typename _Range, typename _Pattern>
    split_view(_Range&&, _Pattern&&)
      -> split_view<views::all_t<_Range>, views::all_t<_Pattern>>;

  template<forward_range _Range>
    split_view(_Range&&, range_value_t<_Range>)
      -> split_view<views::all_t<_Range>, single_view<range_value_t<_Range>>>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range, typename _Pattern>
	concept __can_split_view
	  = requires { split_view(std::declval<_Range>(), std::declval<_Pattern>()); };
    } // namespace __detail

    struct _Split : __adaptor::_RangeAdaptor<_Split>
    {
      template<viewable_range _Range, typename _Pattern>
	requires __detail::__can_split_view<_Range, _Pattern>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r, _Pattern&& __f) const
	{
	  return split_view(std::forward<_Range>(__r), std::forward<_Pattern>(__f));
	}

      using _RangeAdaptor<_Split>::operator();
      static constexpr int _S_arity = 2;
      template<typename _Pattern>
	static constexpr bool _S_has_simple_extra_args
	  = _LazySplit::_S_has_simple_extra_args<_Pattern>;
    };

    inline constexpr _Split split;
  } // namespace views

  namespace views
  {
    struct _Counted
    {
      template<input_or_output_iterator _Iter>
      constexpr auto
      operator() [[nodiscard]] (_Iter __i, iter_difference_t<_Iter> __n) const
      {
	if constexpr (contiguous_iterator<_Iter>)
	  return span(std::__to_address(__i), __n);
	else if constexpr (random_access_iterator<_Iter>)
	  return subrange(__i, __i + __n);
	else
	  return subrange(counted_iterator(std::move(__i), __n),
			  default_sentinel);
      }
    };

    inline constexpr _Counted counted{};
  } // namespace views

  template<view _Vp>
    requires (!common_range<_Vp>) && copyable<iterator_t<_Vp>>
    class common_view : public view_interface<common_view<_Vp>>
    {
    private:
      _Vp _M_base = _Vp();

    public:
      common_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      common_view(_Vp __r)
	: _M_base(std::move(__r))
      { }

      /* XXX: LWG 3280 didn't remove this constructor, but I think it should?
      template<viewable_range _Range>
	requires (!common_range<_Range>)
	  && constructible_from<_Vp, views::all_t<_Range>>
	constexpr explicit
	common_view(_Range&& __r)
	  : _M_base(views::all(std::forward<_Range>(__r)))
	{ }
      */

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin()
      {
	if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
	  return ranges::begin(_M_base);
	else
	  return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
		  (ranges::begin(_M_base));
      }

      constexpr auto
      begin() const requires range<const _Vp>
      {
	if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
	  return ranges::begin(_M_base);
	else
	  return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
		  (ranges::begin(_M_base));
      }

      constexpr auto
      end()
      {
	if constexpr (random_access_range<_Vp> && sized_range<_Vp>)
	  return ranges::begin(_M_base) + ranges::size(_M_base);
	else
	  return common_iterator<iterator_t<_Vp>, sentinel_t<_Vp>>
		  (ranges::end(_M_base));
      }

      constexpr auto
      end() const requires range<const _Vp>
      {
	if constexpr (random_access_range<const _Vp> && sized_range<const _Vp>)
	  return ranges::begin(_M_base) + ranges::size(_M_base);
	else
	  return common_iterator<iterator_t<const _Vp>, sentinel_t<const _Vp>>
		  (ranges::end(_M_base));
      }

      constexpr auto
      size() requires sized_range<_Vp>
      { return ranges::size(_M_base); }

      constexpr auto
      size() const requires sized_range<const _Vp>
      { return ranges::size(_M_base); }
    };

  template<typename _Range>
    common_view(_Range&&) -> common_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<common_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename _Range>
	concept __already_common = common_range<_Range>
	  && requires { views::all(std::declval<_Range>()); };

      template<typename _Range>
	concept __can_common_view
	  = requires { common_view{std::declval<_Range>()}; };
    } // namespace __detail

    struct _Common : __adaptor::_RangeAdaptorClosure
    {
      template<viewable_range _Range>
	requires __detail::__already_common<_Range>
	  || __detail::__can_common_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{
	  if constexpr (__detail::__already_common<_Range>)
	    return views::all(std::forward<_Range>(__r));
	  else
	    return common_view{std::forward<_Range>(__r)};
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _Common common;
  } // namespace views

  template<view _Vp>
    requires bidirectional_range<_Vp>
    class reverse_view : public view_interface<reverse_view<_Vp>>
    {
    private:
      static constexpr bool _S_needs_cached_begin
	= !common_range<_Vp> && !(random_access_range<_Vp>
				  && sized_sentinel_for<sentinel_t<_Vp>,
							iterator_t<_Vp>>);

      _Vp _M_base = _Vp();
      [[no_unique_address]]
	__detail::__maybe_present_t<_S_needs_cached_begin,
				    __detail::_CachedPosition<_Vp>>
				      _M_cached_begin;

    public:
      reverse_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      reverse_view(_Vp __r)
	: _M_base(std::move(__r))
	{ }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr reverse_iterator<iterator_t<_Vp>>
      begin()
      {
	if constexpr (_S_needs_cached_begin)
	  if (_M_cached_begin._M_has_value())
	    return std::make_reverse_iterator(_M_cached_begin._M_get(_M_base));

	auto __it = ranges::next(ranges::begin(_M_base), ranges::end(_M_base));
	if constexpr (_S_needs_cached_begin)
	  _M_cached_begin._M_set(_M_base, __it);
	return std::make_reverse_iterator(std::move(__it));
      }

      constexpr auto
      begin() requires common_range<_Vp>
      { return std::make_reverse_iterator(ranges::end(_M_base)); }

      constexpr auto
      begin() const requires common_range<const _Vp>
      { return std::make_reverse_iterator(ranges::end(_M_base)); }

      constexpr reverse_iterator<iterator_t<_Vp>>
      end()
      { return std::make_reverse_iterator(ranges::begin(_M_base)); }

      constexpr auto
      end() const requires common_range<const _Vp>
      { return std::make_reverse_iterator(ranges::begin(_M_base)); }

      constexpr auto
      size() requires sized_range<_Vp>
      { return ranges::size(_M_base); }

      constexpr auto
      size() const requires sized_range<const _Vp>
      { return ranges::size(_M_base); }
    };

  template<typename _Range>
    reverse_view(_Range&&) -> reverse_view<views::all_t<_Range>>;

  template<typename _Tp>
    inline constexpr bool enable_borrowed_range<reverse_view<_Tp>>
      = enable_borrowed_range<_Tp>;

  namespace views
  {
    namespace __detail
    {
      template<typename>
	inline constexpr bool __is_reversible_subrange = false;

      template<typename _Iter, subrange_kind _Kind>
	inline constexpr bool
	  __is_reversible_subrange<subrange<reverse_iterator<_Iter>,
					    reverse_iterator<_Iter>,
					    _Kind>> = true;

      template<typename>
	inline constexpr bool __is_reverse_view = false;

      template<typename _Vp>
	inline constexpr bool __is_reverse_view<reverse_view<_Vp>> = true;

      template<typename _Range>
	concept __can_reverse_view
	  = requires { reverse_view{std::declval<_Range>()}; };
    } // namespace __detail

    struct _Reverse : __adaptor::_RangeAdaptorClosure
    {
      template<viewable_range _Range>
	requires __detail::__is_reverse_view<remove_cvref_t<_Range>>
	  || __detail::__is_reversible_subrange<remove_cvref_t<_Range>>
	  || __detail::__can_reverse_view<_Range>
	constexpr auto
	operator() [[nodiscard]] (_Range&& __r) const
	{
	  using _Tp = remove_cvref_t<_Range>;
	  if constexpr (__detail::__is_reverse_view<_Tp>)
	    return std::forward<_Range>(__r).base();
	  else if constexpr (__detail::__is_reversible_subrange<_Tp>)
	    {
	      using _Iter = decltype(ranges::begin(__r).base());
	      if constexpr (sized_range<_Tp>)
		return subrange<_Iter, _Iter, subrange_kind::sized>
			{__r.end().base(), __r.begin().base(), __r.size()};
	      else
		return subrange<_Iter, _Iter, subrange_kind::unsized>
			{__r.end().base(), __r.begin().base()};
	    }
	  else
	    return reverse_view{std::forward<_Range>(__r)};
	}

      static constexpr bool _S_has_simple_call_op = true;
    };

    inline constexpr _Reverse reverse;
  } // namespace views

  namespace __detail
  {
    template<typename _Tp, size_t _Nm>
    concept __has_tuple_element = requires(_Tp __t)
      {
	typename tuple_size<_Tp>::type;
	requires _Nm < tuple_size_v<_Tp>;
	typename tuple_element_t<_Nm, _Tp>;
	{ std::get<_Nm>(__t) }
	  -> convertible_to<const tuple_element_t<_Nm, _Tp>&>;
      };

    template<typename _Tp, size_t _Nm>
      concept __returnable_element
	= is_reference_v<_Tp> || move_constructible<tuple_element_t<_Nm, _Tp>>;
  }

  template<input_range _Vp, size_t _Nm>
    requires view<_Vp>
      && __detail::__has_tuple_element<range_value_t<_Vp>, _Nm>
      && __detail::__has_tuple_element<remove_reference_t<range_reference_t<_Vp>>,
				       _Nm>
      && __detail::__returnable_element<range_reference_t<_Vp>, _Nm>
    class elements_view : public view_interface<elements_view<_Vp, _Nm>>
    {
    public:
      elements_view() requires default_initializable<_Vp> = default;

      constexpr explicit
      elements_view(_Vp base)
	: _M_base(std::move(base))
      { }

      constexpr _Vp
      base() const& requires copy_constructible<_Vp>
      { return _M_base; }

      constexpr _Vp
      base() &&
      { return std::move(_M_base); }

      constexpr auto
      begin() requires (!__detail::__simple_view<_Vp>)
      { return _Iterator<false>(ranges::begin(_M_base)); }

      constexpr auto
      begin() const requires range<const _Vp>
      { return _Iterator<true>(ranges::begin(_M_base)); }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp> && !common_range<_Vp>)
      { return _Sentinel<false>{ranges::end(_M_base)}; }

      constexpr auto
      end() requires (!__detail::__simple_view<_Vp> && common_range<_Vp>)
      { return _Iterator<false>{ranges::end(_M_base)}; }

      constexpr auto
      end() const requires range<const _Vp>
      { return _Sentinel<true>{ranges::end(_M_base)}; }

      constexpr auto
      end() const requires common_range<const _Vp>
      { return _Iterator<true>{ranges::end(_M_base)}; }

      constexpr auto
      size() requires sized_range<_Vp>
      { return ranges::size(_M_base); }

      constexpr auto
      size() const requires sized_range<const _Vp>
      { return ranges::size(_M_base); }

    private:
      template<bool _Const>
	using _Base = __detail::__maybe_const_t<_Const, _Vp>;

      template<bool _Const>
	struct __iter_cat
	{ };

      template<bool _Const>
	requires forward_range<_Base<_Const>>
	struct __iter_cat<_Const>
	{
	private:
	  static auto _S_iter_cat()
	  {
	    using _Base = elements_view::_Base<_Const>;
	    using _Cat = typename iterator_traits<iterator_t<_Base>>::iterator_category;
	    using _Res = decltype((std::get<_Nm>(*std::declval<iterator_t<_Base>>())));
	    if constexpr (!is_lvalue_reference_v<_Res>)
	      return input_iterator_tag{};
	    else if constexpr (derived_from<_Cat, random_access_iterator_tag>)
	      return random_access_iterator_tag{};
	    else
	      return _Cat{};
	  }
	public:
	  using iterator_category = decltype(_S_iter_cat());
	};

      template<bool _Const>
	struct _Sentinel;

      template<bool _Const>
	struct _Iterator : __iter_cat<_Const>
	{
	private:
	  using _Base = elements_view::_Base<_Const>;

	  iterator_t<_Base> _M_current = iterator_t<_Base>();

	  static constexpr decltype(auto)
	  _S_get_element(const iterator_t<_Base>& __i)
	  {
	    if constexpr (is_reference_v<range_reference_t<_Base>>)
	      return std::get<_Nm>(*__i);
	    else
	      {
		using _Et = remove_cv_t<tuple_element_t<_Nm, range_reference_t<_Base>>>;
		return static_cast<_Et>(std::get<_Nm>(*__i));
	      }
	  }

	  static auto
	  _S_iter_concept()
	  {
	    if constexpr (random_access_range<_Base>)
	      return random_access_iterator_tag{};
	    else if constexpr (bidirectional_range<_Base>)
	      return bidirectional_iterator_tag{};
	    else if constexpr (forward_range<_Base>)
	      return forward_iterator_tag{};
	    else
	      return input_iterator_tag{};
	  }

	  friend _Iterator<!_Const>;

	public:
	  using iterator_concept = decltype(_S_iter_concept());
	  // iterator_category defined in elements_view::__iter_cat
	  using value_type
	    = remove_cvref_t<tuple_element_t<_Nm, range_value_t<_Base>>>;
	  using difference_type = range_difference_t<_Base>;

	  _Iterator() requires default_initializable<iterator_t<_Base>> = default;

	  constexpr explicit
	  _Iterator(iterator_t<_Base> current)
	    : _M_current(std::move(current))
	  { }

	  constexpr
	  _Iterator(_Iterator<!_Const> i)
	    requires _Const && convertible_to<iterator_t<_Vp>, iterator_t<_Base>>
	    : _M_current(std::move(i._M_current))
	  { }

	  constexpr const iterator_t<_Base>&
	  base() const& noexcept
	  { return _M_current; }

	  constexpr iterator_t<_Base>
	  base() &&
	  { return std::move(_M_current); }

	  constexpr decltype(auto)
	  operator*() const
	  { return _S_get_element(_M_current); }

	  constexpr _Iterator&
	  operator++()
	  {
	    ++_M_current;
	    return *this;
	  }

	  constexpr void
	  operator++(int)
	  { ++_M_current; }

	  constexpr _Iterator
	  operator++(int) requires forward_range<_Base>
	  {
	    auto __tmp = *this;
	    ++_M_current;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator--() requires bidirectional_range<_Base>
	  {
	    --_M_current;
	    return *this;
	  }

	  constexpr _Iterator
	  operator--(int) requires bidirectional_range<_Base>
	  {
	    auto __tmp = *this;
	    --_M_current;
	    return __tmp;
	  }

	  constexpr _Iterator&
	  operator+=(difference_type __n)
	    requires random_access_range<_Base>
	  {
	    _M_current += __n;
	    return *this;
	  }

	  constexpr _Iterator&
	  operator-=(difference_type __n)
	    requires random_access_range<_Base>
	  {
	    _M_current -= __n;
	    return *this;
	  }

	  constexpr decltype(auto)
	  operator[](difference_type __n) const
	    requires random_access_range<_Base>
	  { return _S_get_element(_M_current + __n); }

	  friend constexpr bool
	  operator==(const _Iterator& __x, const _Iterator& __y)
	    requires equality_comparable<iterator_t<_Base>>
	  { return __x._M_current == __y._M_current; }

	  friend constexpr bool
	  operator<(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __x._M_current < __y._M_current; }

	  friend constexpr bool
	  operator>(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __y._M_current < __x._M_current; }

	  friend constexpr bool
	  operator<=(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return !(__y._M_current > __x._M_current); }

	  friend constexpr bool
	  operator>=(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return !(__x._M_current > __y._M_current); }

#ifdef __cpp_lib_three_way_comparison
	  friend constexpr auto
	  operator<=>(const _Iterator& __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	      && three_way_comparable<iterator_t<_Base>>
	  { return __x._M_current <=> __y._M_current; }
#endif

	  friend constexpr _Iterator
	  operator+(const _Iterator& __x, difference_type __y)
	    requires random_access_range<_Base>
	  { return _Iterator{__x} += __y; }

	  friend constexpr _Iterator
	  operator+(difference_type __x, const _Iterator& __y)
	    requires random_access_range<_Base>
	  { return __y + __x; }

	  friend constexpr _Iterator
	  operator-(const _Iterator& __x, difference_type __y)
	    requires random_access_range<_Base>
	  { return _Iterator{__x} -= __y; }

	  // _GLIBCXX_RESOLVE_LIB_DEFECTS
	  // 3483. transform_view::iterator's difference is overconstrained
	  friend constexpr difference_type
	  operator-(const _Iterator& __x, const _Iterator& __y)
	    requires sized_sentinel_for<iterator_t<_Base>, iterator_t<_Base>>
	  { return __x._M_current - __y._M_current; }

	  template <bool> friend struct _Sentinel;
	};

      template<bool _Const>
	struct _Sentinel
	{
	private:
	  template<bool _Const2>
	    constexpr bool
	    _M_equal(const _Iterator<_Const2>& __x) const
	    { return __x._M_current == _M_end; }

	  template<bool _Const2>
	    constexpr auto
	    _M_distance_from(const _Iterator<_Const2>& __i) const
	    { return _M_end - __i._M_current; }

	  using _Base = elements_view::_Base<_Const>;
	  sentinel_t<_Base> _M_end = sentinel_t<_Base>();

	public:
	  _Sentinel() = default;

	  constexpr explicit
	  _Sentinel(sentinel_t<_Base> __end)
	    : _M_end(std::move(__end))
	  { }

	  constexpr
	  _Sentinel(_Sentinel<!_Const> __other)
	    requires _Const
	      && convertible_to<sentinel_t<_Vp>, sentinel_t<_Base>>
	    : _M_end(std::move(__other._M_end))
	  { }

	  constexpr sentinel_t<_Base>
	  base() const
	  { return _M_end; }

	  template<bool _Const2>
	    requires sentinel_for<sentinel_t<_Base>,
		       iterator_t<__detail::__maybe_const_t<_Const2, _Vp>>>
	    friend constexpr bool
	    operator==(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return __y._M_equal(__x); }

	  template<bool _Const2,
		   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
	    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	    friend constexpr range_difference_t<_Base2>
	    operator-(const _Iterator<_Const2>& __x, const _Sentinel& __y)
	    { return -__y._M_distance_from(__x); }

	  template<bool _Const2,
		   typename _Base2 = __detail::__maybe_const_t<_Const2, _Vp>>
	    requires sized_sentinel_for<sentinel_t<_Base>, iterator_t<_Base2>>
	    friend constexpr range_difference_t<_Base2>
	    operator-(const _Sentinel& __x, const _Iterator<_Const2>& __y)
	    { return __x._M_distance_from(__y); }

	  friend _Sentinel<!_Const>;
	};

      _Vp _M_base = _Vp();
    };

  template<typename _Tp, size_t _Nm>
    inline constexpr bool enable_borrowed_range<elements_view<_Tp, _Nm>>
      = enable_borrowed_range<_Tp>;

  template<typename _Range>
    using keys_view = elements_view<views::all_t<_Range>, 0>;

  template<typename _Range>
    using values_view = elements_view<views::all_t<_Range>, 1>;

  namespace views
  {
    namespace __detail
    {
      template<size_t _Nm, typename _Range>
	concept __can_elements_view
	  = requires { elements_view<all_t<_Range>, _Nm>{std::declval<_Range>()}; };
    } // namespace __detail

    template<size_t _Nm>
      struct _Elements : __adaptor::_RangeAdaptorClosure
      {
	template<viewable_range _Range>
	  requires __detail::__can_elements_view<_Nm, _Range>
	  constexpr auto
	  operator() [[nodiscard]] (_Range&& __r) const
	  {
	    return elements_view<all_t<_Range>, _Nm>{std::forward<_Range>(__r)};
	  }

	static constexpr bool _S_has_simple_call_op = true;
      };

    template<size_t _Nm>
      inline constexpr _Elements<_Nm> elements;
    inline constexpr auto keys = elements<0>;
    inline constexpr auto values = elements<1>;
  } // namespace views

} // namespace ranges

  namespace views = ranges::views;

_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
#endif // library concepts
#endif // C++2a
#endif /* _GLIBCXX_RANGES */
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     H                                                          X                           1                             ]                     
                                                          
            $                    	                                                                                     l                             0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  3~</64NjUiQ岚׾mh◬< Z/<3ZD,x3]j&%WL+vu-z&mtE'5RErny+`jnd(tޖ\(j
F@.ch$.1Oa+}!"d25VWE؏zɓRJa*bC<y<nGI`Y4	&BH2         ~Module signature appended~
 070701000A0397000081A4000000000000000000000001682F6DA7000031B3000000CA0000000200000000000000000000004100000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/phy/davicom.ko  ELF          >                    0'          @     @ # "          GNU ƫXP8jn`        Linux                Linux   6.1.0-37-amd64      SH(     H      xu1[    H       [    H    1ې    SH(  1H         xo  tj  uU(  H         x?(   x     H      x(  H     1[    [      ff.          SH(  1H         x1H    1҅O[         UH   S(  H      ÅxL   (  H  x?Ⱥ       Åu (  H         1҅NЉӉ[]           yÉ[]    ً(  [   H    ]        H       H           H                                                Davicom DM9161E Davicom DM9161B/C Davicom DM9161A Davicom DM9131 license=GPL author=Andy Fleming description=Davicom PHY driver alias=mdio:????000000011000000110111000???? alias=mdio:????000110000001101110001010???? alias=mdio:????000110000001101110001011???? alias=mdio:????000110000001101110001000???? depends=libphy retpoline=Y intree=Y name=davicom vermagic=6.1.0-37-amd64 SMP preempt mod_unload modversions                                                                                                                                                                                                                                                                                                                   m    __fentry__                                              ![Ha    phy_drivers_register                                    ;    mdiobus_read                                            9[    __x86_return_thunk                                      D    phy_trigger_machine                                         phy_error                                               XV    mdiobus_write                                                phy_drivers_unregister                                  (    __genphy_config_aneg                                    zR    module_layout                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     davicom                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0  GCC: (Debian 12.2.0-14+deb12u1) 12.2.0                  A=      h                           @j                   X       P=       `=    p         
      
  p=    ] =    ]       
     
  =    ` =    ]        
9             c    
          
d mdio_device_id phy_module_exit phy_module_init dm9161_config_init dm9161_config_aneg dm9161_handle_interrupt dm9161_config_intr davicom.ko  k1-                                                                                                                                               ?       ,            k       ,       +            ,       @            ,       U                   l                   y                        
      	                  
                   <                                       $                                @       `                  O           P              .                   >           =       Q    @             d            (       p                                                                                              
                                       %                   4                     ?                   K                     b                     o            (                                                                                                                 __UNIQUE_ID_alias197 __UNIQUE_ID_alias196 __UNIQUE_ID_alias195 __UNIQUE_ID_alias194 __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 phy_module_init dm91xx_driver dm9161_handle_interrupt dm9161_config_init phy_module_exit dm9161_config_aneg dm9161_config_intr davicom_tbl __UNIQUE_ID___addressable_cleanup_module389 __UNIQUE_ID___addressable_init_module388 __UNIQUE_ID_license387 __UNIQUE_ID_author386 __UNIQUE_ID_description385 phy_error __this_module cleanup_module __fentry// -*- C++ -*-
//===-- algorithm_impl.h --------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _PSTL_ALGORITHM_IMPL_H
#define _PSTL_ALGORITHM_IMPL_H

#include <iterator>
#include <type_traits>
#include <utility>
#include <functional>
#include <algorithm>

#include "execution_impl.h"
#include "memory_impl.h"
#include "parallel_backend_utils.h"
#include "parallel_backend.h"
#include "parallel_impl.h"
#include "unseq_backend_simd.h"


namespace __pstl
{
namespace __internal
{

//------------------------------------------------------------------------
// any_of
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Pred>
bool
__brick_any_of(const _ForwardIterator __first, const _ForwardIterator __last, _Pred __pred,
               /*__is_vector=*/std::false_type) noexcept
{
    return std::any_of(__first, __last, __pred);
};

template <class _ForwardIterator, class _Pred>
bool
__brick_any_of(const _ForwardIterator __first, const _ForwardIterator __last, _Pred __pred,
               /*__is_vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_or(__first, __last - __first, __pred);
};

template <class _ExecutionPolicy, class _ForwardIterator, class _Pred, class _IsVector>
bool
__pattern_any_of(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred,
                 _IsVector __is_vector, /*parallel=*/std::false_type) noexcept
{
    return __internal::__brick_any_of(__first, __last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Pred, class _IsVector>
bool
__pattern_any_of(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Pred __pred,
                 _IsVector __is_vector, /*parallel=*/std::true_type)
{
    return __internal::__except_handler([&]() {
        return __internal::__parallel_or(std::forward<_ExecutionPolicy>(__exec), __first, __last,
                                         [__pred, __is_vector](_ForwardIterator __i, _ForwardIterator __j) {
                                             return __internal::__brick_any_of(__i, __j, __pred, __is_vector);
                                         });
    });
}

// [alg.foreach]
// for_each_n with no policy

template <class _ForwardIterator, class _Size, class _Function>
_ForwardIterator
__for_each_n_it_serial(_ForwardIterator __first, _Size __n, _Function __f)
{
    for (; __n > 0; ++__first, --__n)
        __f(__first);
    return __first;
}

//------------------------------------------------------------------------
// walk1 (pseudo)
//
// walk1 evaluates f(x) for each dereferenced value x drawn from [first,last)
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Function>
void
__brick_walk1(_ForwardIterator __first, _ForwardIterator __last, _Function __f, /*vector=*/std::false_type) noexcept
{
    std::for_each(__first, __last, __f);
}

template <class _RandomAccessIterator, class _Function>
void
__brick_walk1(_RandomAccessIterator __first, _RandomAccessIterator __last, _Function __f,
              /*vector=*/std::true_type) noexcept
{
    __unseq_backend::__simd_walk_1(__first, __last - __first, __f);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Function, class _IsVector>
void
__pattern_walk1(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Function __f,
                _IsVector __is_vector,
                /*parallel=*/std::false_type) noexcept
{
    __internal::__brick_walk1(__first, __last, __f, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Function, class _IsVector>
void
__pattern_walk1(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Function __f,
                _IsVector __is_vector,
                /*parallel=*/std::true_type)
{
    __internal::__except_handler([&]() {
        __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
                                      [__f, __is_vector](_ForwardIterator __i, _ForwardIterator __j) {
                                          __internal::__brick_walk1(__i, __j, __f, __is_vector);
                                      });
    });
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Brick>
void
__pattern_walk_brick(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick,
                     /*parallel=*/std::false_type) noexcept
{
    __brick(__first, __last);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Brick>
void
__pattern_walk_brick(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Brick __brick,
                     /*parallel=*/std::true_type)
{
    __internal::__except_handler([&]() {
        __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
                                      [__brick](_ForwardIterator __i, _ForwardIterator __j) { __brick(__i, __j); });
    });
}

//------------------------------------------------------------------------
// walk1_n
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Size, class _Function>
_ForwardIterator
__brick_walk1_n(_ForwardIterator __first, _Size __n, _Function __f, /*_IsVectorTag=*/std::false_type)
{
    return __internal::__for_each_n_it_serial(__first, __n,
                                              [&__f](_ForwardIterator __it) { __f(*__it); }); // calling serial version
}

template <class _RandomAccessIterator, class _DifferenceType, class _Function>
_RandomAccessIterator
__brick_walk1_n(_RandomAccessIterator __first, _DifferenceType __n, _Function __f,
                /*vectorTag=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_walk_1(__first, __n, __f);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Function, class _IsVector>
_ForwardIterator
__pattern_walk1_n(_ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Function __f, _IsVector __is_vector,
                  /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_walk1_n(__first, __n, __f, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Function, class _IsVector>
_RandomAccessIterator
__pattern_walk1_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, _Function __f,
                  _IsVector __is_vector,
                  /*is_parallel=*/std::true_type)
{
    __internal::__pattern_walk1(std::forward<_ExecutionPolicy>(__exec), __first, __first + __n, __f, __is_vector,
                                std::true_type());
    return __first + __n;
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Brick>
_ForwardIterator
__pattern_walk_brick_n(_ExecutionPolicy&&, _ForwardIterator __first, _Size __n, _Brick __brick,
                       /*is_parallel=*/std::false_type) noexcept
{
    return __brick(__first, __n);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Brick>
_RandomAccessIterator
__pattern_walk_brick_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _Size __n, _Brick __brick,
                       /*is_parallel=*/std::true_type)
{
    return __internal::__except_handler([&]() {
        __par_backend::__parallel_for(
            std::forward<_ExecutionPolicy>(__exec), __first, __first + __n,
            [__brick](_RandomAccessIterator __i, _RandomAccessIterator __j) { __brick(__i, __j - __i); });
        return __first + __n;
    });
}

//------------------------------------------------------------------------
// walk2 (pseudo)
//
// walk2 evaluates f(x,y) for deferenced values (x,y) drawn from [first1,last1) and [first2,...)
//------------------------------------------------------------------------
template <class _ForwardIterator1, class _ForwardIterator2, class _Function>
_ForwardIterator2
__brick_walk2(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f,
              /*vector=*/std::false_type) noexcept
{
    for (; __first1 != __last1; ++__first1, ++__first2)
        __f(*__first1, *__first2);
    return __first2;
}

template <class _ForwardIterator1, class _ForwardIterator2, class _Function>
_ForwardIterator2
__brick_walk2(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _Function __f,
              /*vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_walk_2(__first1, __last1 - __first1, __first2, __f);
}

template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function>
_ForwardIterator2
__brick_walk2_n(_ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, _Function __f,
                /*vector=*/std::false_type) noexcept
{
    for (; __n > 0; --__n, ++__first1, ++__first2)
        __f(*__first1, *__first2);
    return __first2;
}

template <class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function>
_ForwardIterator2
__brick_walk2_n(_ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, _Function __f,
                /*vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_walk_2(__first1, __n, __first2, __f);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function, class _IsVector>
_ForwardIterator2
__pattern_walk2(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                _Function __f, _IsVector __is_vector, /*parallel=*/std::false_type) noexcept
{
    return __internal::__brick_walk2(__first1, __last1, __first2, __f, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Function, class _IsVector>
_ForwardIterator2
__pattern_walk2(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                _ForwardIterator2 __first2, _Function __f, _IsVector __is_vector, /*parallel=*/std::true_type)
{
    return __internal::__except_handler([&]() {
        __par_backend::__parallel_for(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
            [__f, __first1, __first2, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) {
                __internal::__brick_walk2(__i, __j, __first2 + (__i - __first1), __f, __is_vector);
            });
        return __first2 + (__last1 - __first1);
    });
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Function,
          class _IsVector>
_ForwardIterator2
__pattern_walk2_n(_ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2, _Function __f,
                  _IsVector __is_vector, /*parallel=*/std::false_type) noexcept
{
    return __internal::__brick_walk2_n(__first1, __n, __first2, __f, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2,
          class _Function, class _IsVector>
_RandomAccessIterator2
__pattern_walk2_n(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _Size __n, _RandomAccessIterator2 __first2,
                  _Function __f, _IsVector __is_vector, /*parallel=*/std::true_type)
{
    return __internal::__pattern_walk2(std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n, __first2, __f,
                                       __is_vector, std::true_type());
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Brick>
_ForwardIterator2
__pattern_walk2_brick(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                      _ForwardIterator2 __first2, _Brick __brick, /*parallel=*/std::false_type) noexcept
{
    return __brick(__first1, __last1, __first2);
}

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _Brick>
_RandomAccessIterator2
__pattern_walk2_brick(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
                      _RandomAccessIterator2 __first2, _Brick __brick, /*parallel=*/std::true_type)
{
    return __internal::__except_handler([&]() {
        __par_backend::__parallel_for(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
            [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
                __brick(__i, __j, __first2 + (__i - __first1));
            });
        return __first2 + (__last1 - __first1);
    });
}

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _Size, class _RandomAccessIterator2, class _Brick>
_RandomAccessIterator2
__pattern_walk2_brick_n(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _Size __n,
                        _RandomAccessIterator2 __first2, _Brick __brick, /*parallel=*/std::true_type)
{
    return __internal::__except_handler([&]() {
        __par_backend::__parallel_for(
            std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n,
            [__first1, __first2, __brick](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
                __brick(__i, __j - __i, __first2 + (__i - __first1));
            });
        return __first2 + __n;
    });
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _Size, class _ForwardIterator2, class _Brick>
_ForwardIterator2
__pattern_walk2_brick_n(_ExecutionPolicy&&, _ForwardIterator1 __first1, _Size __n, _ForwardIterator2 __first2,
                        _Brick __brick, /*parallel=*/std::false_type) noexcept
{
    return __brick(__first1, __n, __first2);
}

//------------------------------------------------------------------------
// walk3 (pseudo)
//
// walk3 evaluates f(x,y,z) for (x,y,z) drawn from [first1,last1), [first2,...), [first3,...)
//------------------------------------------------------------------------
template <class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3, class _Function>
_ForwardIterator3
__brick_walk3(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
              _ForwardIterator3 __first3, _Function __f, /*vector=*/std::false_type) noexcept
{
    for (; __first1 != __last1; ++__first1, ++__first2, ++__first3)
        __f(*__first1, *__first2, *__first3);
    return __first3;
}

template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _RandomAccessIterator3, class _Function>
_RandomAccessIterator3
__brick_walk3(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
              _RandomAccessIterator3 __first3, _Function __f, /*vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_walk_3(__first1, __last1 - __first1, __first2, __first3, __f);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _ForwardIterator3,
          class _Function, class _IsVector>
_ForwardIterator3
__pattern_walk3(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                _ForwardIterator3 __first3, _Function __f, _IsVector __is_vector, /*parallel=*/std::false_type) noexcept
{
    return __internal::__brick_walk3(__first1, __last1, __first2, __first3, __f, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2,
          class _RandomAccessIterator3, class _Function, class _IsVector>
_RandomAccessIterator3
__pattern_walk3(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
                _RandomAccessIterator2 __first2, _RandomAccessIterator3 __first3, _Function __f, _IsVector __is_vector,
                /*parallel=*/std::true_type)
{
    return __internal::__except_handler([&]() {
        __par_backend::__parallel_for(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
            [__f, __first1, __first2, __first3, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
                __internal::__brick_walk3(__i, __j, __first2 + (__i - __first1), __first3 + (__i - __first1), __f,
                                          __is_vector);
            });
        return __first3 + (__last1 - __first1);
    });
}

//------------------------------------------------------------------------
// equal
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
bool
__brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
              _ForwardIterator2 __last2, _BinaryPredicate __p, /* IsVector = */ std::false_type) noexcept
{
    return std::equal(__first1, __last1, __first2, __last2, __p);
}

template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
bool
__brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
              _RandomAccessIterator2 __last2, _BinaryPredicate __p, /* is_vector = */ std::true_type) noexcept
{
    if (__last1 - __first1 != __last2 - __first2)
        return false;

    return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
bool
__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                _ForwardIterator2 __last2, _BinaryPredicate __p, _IsVector __is_vector, /* is_parallel = */
                std::false_type) noexcept
{
    return __internal::__brick_equal(__first1, __last1, __first2, __last2, __p, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate,
          class _IsVector>
bool
__pattern_equal(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
                _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _BinaryPredicate __p,
                _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
    if (__last1 - __first1 != __last2 - __first2)
        return false;

    return __internal::__except_handler([&]() {
        return !__internal::__parallel_or(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
            [__first1, __first2, __p, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
                return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1),
                                                  __p, __is_vector);
            });
    });
}

//------------------------------------------------------------------------
// equal version for sequences with equal length
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
bool
__brick_equal(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _BinaryPredicate __p,
              /* IsVector = */ std::false_type) noexcept
{
    return std::equal(__first1, __last1, __first2, __p);
}

template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate>
bool
__brick_equal(_RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1, _RandomAccessIterator2 __first2,
              _BinaryPredicate __p, /* is_vector = */ std::true_type) noexcept
{
    return __unseq_backend::__simd_first(__first1, __last1 - __first1, __first2, std::not_fn(__p)).first == __last1;
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
bool
__pattern_equal(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                _BinaryPredicate __p, _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept
{
    return __internal::__brick_equal(__first1, __last1, __first2, __p, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate,
          class _IsVector>
bool
__pattern_equal(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
                _RandomAccessIterator2 __first2, _BinaryPredicate __p, _IsVector __is_vector,
                /*is_parallel=*/std::true_type)
{
    return __internal::__except_handler([&]() {
        return !__internal::__parallel_or(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
            [__first1, __first2, __p, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
                return !__internal::__brick_equal(__i, __j, __first2 + (__i - __first1), __p, __is_vector);
            });
    });
}

//------------------------------------------------------------------------
// find_if
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Predicate>
_ForwardIterator
__brick_find_if(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
                /*is_vector=*/std::false_type) noexcept
{
    return std::find_if(__first, __last, __pred);
}

template <class _RandomAccessIterator, class _Predicate>
_RandomAccessIterator
__brick_find_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _Predicate __pred,
                /*is_vector=*/std::true_type) noexcept
{
    typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType;
    return __unseq_backend::__simd_first(
        __first, _SizeType(0), __last - __first,
        [&__pred](_RandomAccessIterator __it, _SizeType __i) { return __pred(__it[__i]); });
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate, class _IsVector>
_ForwardIterator
__pattern_find_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
                  _IsVector __is_vector,
                  /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_find_if(__first, __last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate, class _IsVector>
_ForwardIterator
__pattern_find_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
                  _IsVector __is_vector,
                  /*is_parallel=*/std::true_type)
{
    return __internal::__except_handler([&]() {
        return __internal::__parallel_find(
            std::forward<_ExecutionPolicy>(__exec), __first, __last,
            [__pred, __is_vector](_ForwardIterator __i, _ForwardIterator __j) {
                return __internal::__brick_find_if(__i, __j, __pred, __is_vector);
            },
            std::less<typename std::iterator_traits<_ForwardIterator>::difference_type>(),
            /*is_first=*/true);
    });
}

//------------------------------------------------------------------------
// find_end
//------------------------------------------------------------------------

// find the first occurrence of the subsequence [s_first, s_last)
//   or the  last occurrence of the subsequence in the range [first, last)
// b_first determines what occurrence we want to find (first or last)
template <class _RandomAccessIterator1, class _RandomAccessIterator2, class _BinaryPredicate, class _IsVector>
_RandomAccessIterator1
__find_subrange(_RandomAccessIterator1 __first, _RandomAccessIterator1 __last, _RandomAccessIterator1 __global_last,
                _RandomAccessIterator2 __s_first, _RandomAccessIterator2 __s_last, _BinaryPredicate __pred,
                bool __b_first, _IsVector __is_vector) noexcept
{
    typedef typename std::iterator_traits<_RandomAccessIterator2>::value_type _ValueType;
    auto __n2 = __s_last - __s_first;
    if (__n2 < 1)
    {
        return __b_first ? __first : __last;
    }

    auto __n1 = __global_last - __first;
    if (__n1 < __n2)
    {
        return __last;
    }

    auto __cur = __last;
    while (__first != __last && (__global_last - __first >= __n2))
    {
        // find position of *s_first in [first, last) (it can be start of subsequence)
        __first = __internal::__brick_find_if(
            __first, __last, __equal_value_by_pred<_ValueType, _BinaryPredicate>(*__s_first, __pred), __is_vector);

        // if position that was found previously is the start of subsequence
        // then we can exit the loop (b_first == true) or keep the position
        // (b_first == false)
        if (__first != __last && (__global_last - __first >= __n2) &&
            __internal::__brick_equal(__s_first + 1, __s_last, __first + 1, __pred, __is_vector))
        {
            if (__b_first)
            {
                return __first;
            }
            else
            {
                __cur = __first;
            }
        }
        else if (__first == __last)
        {
            break;
        }
        else
        {
        }

        // in case of b_first == false we try to find new start position
        // for the next subsequence
        ++__first;
    }
    return __cur;
}

template <class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate, class _IsVector>
_RandomAccessIterator
__find_subrange(_RandomAccessIterator __first, _RandomAccessIterator __last, _RandomAccessIterator __global_last,
                _Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector) noexcept
{
    if (static_cast<_Size>(__global_last - __first) < __count || __count < 1)
    {
        return __last; // According to the standard last shall be returned when count < 1
    }

    auto __unary_pred = __equal_value_by_pred<_Tp, _BinaryPredicate>(__value, __pred);
    while (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count))
    {
        __first = __internal::__brick_find_if(__first, __last, __unary_pred, __is_vector);

        // check that all of elements in [first+1, first+count) equal to value
        if (__first != __last && (static_cast<_Size>(__global_last - __first) >= __count) &&
            !__internal::__brick_any_of(__first + 1, __first + __count, std::not_fn(__unary_pred), __is_vector))
        {
            return __first;
        }
        else if (__first == __last)
        {
            break;
        }
        else
        {
            ++__first;
        }
    }
    return __last;
}

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1
__brick_find_end(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
                 _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::false_type) noexcept
{
    return std::find_end(__first, __last, __s_first, __s_last, __pred);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1
__brick_find_end(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
                 _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept
{
    return __find_subrange(__first, __last, __last, __s_first, __s_last, __pred, false, std::true_type());
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_find_end(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
                   _ForwardIterator2 __s_last, _BinaryPredicate __pred, _IsVector __is_vector,
                   /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_find_end(__first, __last, __s_first, __s_last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_find_end(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
                   _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred,
                   _IsVector __is_vector, /*is_parallel=*/std::true_type) noexcept
{
    if (__last - __first == __s_last - __s_first)
    {
        const bool __res = __internal::__pattern_equal(std::forward<_ExecutionPolicy>(__exec), __first, __last,
                                                       __s_first, __pred, __is_vector, std::true_type());
        return __res ? __first : __last;
    }
    else
    {
        return __internal::__except_handler([&]() {
            return __internal::__parallel_find(
                std::forward<_ExecutionPolicy>(__exec), __first, __last,
                [__last, __s_first, __s_last, __pred, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) {
                    return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, false,
                                                       __is_vector);
                },
                std::greater<typename std::iterator_traits<_ForwardIterator1>::difference_type>(), /*is_first=*/false);
        });
    }
}

//------------------------------------------------------------------------
// find_first_of
//------------------------------------------------------------------------
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1
__brick_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
                      _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::false_type) noexcept
{
    return std::find_first_of(__first, __last, __s_first, __s_last, __pred);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1
__brick_find_first_of(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
                      _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*__is_vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_find_first_of(__first, __last, __s_first, __s_last, __pred);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_find_first_of(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last,
                        _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred,
                        _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_find_first_of(__first, __last, __s_first, __s_last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_find_first_of(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
                        _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred,
                        _IsVector __is_vector, /*is_parallel=*/std::true_type) noexcept
{
    return __internal::__except_handler([&]() {
        return __internal::__parallel_find(
            std::forward<_ExecutionPolicy>(__exec), __first, __last,
            [__s_first, __s_last, __pred, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) {
                return __internal::__brick_find_first_of(__i, __j, __s_first, __s_last, __pred, __is_vector);
            },
            std::less<typename std::iterator_traits<_ForwardIterator1>::difference_type>(), /*is_first=*/true);
    });
}

//------------------------------------------------------------------------
// search
//------------------------------------------------------------------------
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1
__brick_search(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
               _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept
{
    return std::search(__first, __last, __s_first, __s_last, __pred);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
_ForwardIterator1
__brick_search(_ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
               _ForwardIterator2 __s_last, _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept
{
    return __internal::__find_subrange(__first, __last, __last, __s_first, __s_last, __pred, true, std::true_type());
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_search(_ExecutionPolicy&&, _ForwardIterator1 __first, _ForwardIterator1 __last, _ForwardIterator2 __s_first,
                 _ForwardIterator2 __s_last, _BinaryPredicate __pred, _IsVector __is_vector,
                 /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_search(__first, __last, __s_first, __s_last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator1
__pattern_search(_ExecutionPolicy&& __exec, _ForwardIterator1 __first, _ForwardIterator1 __last,
                 _ForwardIterator2 __s_first, _ForwardIterator2 __s_last, _BinaryPredicate __pred,
                 _IsVector __is_vector,
                 /*is_parallel=*/std::true_type) noexcept
{
    if (__last - __first == __s_last - __s_first)
    {
        const bool __res = __internal::__pattern_equal(std::forward<_ExecutionPolicy>(__exec), __first, __last,
                                                       __s_first, __pred, __is_vector, std::true_type());
        return __res ? __first : __last;
    }
    else
    {
        return __internal::__except_handler([&]() {
            return __internal::__parallel_find(
                std::forward<_ExecutionPolicy>(__exec), __first, __last,
                [__last, __s_first, __s_last, __pred, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) {
                    return __internal::__find_subrange(__i, __j, __last, __s_first, __s_last, __pred, true,
                                                       __is_vector);
                },
                std::less<typename std::iterator_traits<_ForwardIterator1>::difference_type>(), /*is_first=*/true);
        });
    }
}

//------------------------------------------------------------------------
// search_n
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
_ForwardIterator
__brick_search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value,
                 _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept
{
    return std::search_n(__first, __last, __count, __value, __pred);
}

template <class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate>
_ForwardIterator
__brick_search_n(_ForwardIterator __first, _ForwardIterator __last, _Size __count, const _Tp& __value,
                 _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept
{
    return __internal::__find_subrange(__first, __last, __last, __count, __value, __pred, std::true_type());
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Size, class _Tp, class _BinaryPredicate,
          class _IsVector>
_ForwardIterator
__pattern_search_n(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Size __count,
                   const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector,
                   /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_search_n(__first, __last, __count, __value, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Size, class _Tp, class _BinaryPredicate,
          class _IsVector>
_RandomAccessIterator
__pattern_search_n(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
                   _Size __count, const _Tp& __value, _BinaryPredicate __pred, _IsVector __is_vector,
                   /*is_parallel=*/std::true_type) noexcept
{
    if (static_cast<_Size>(__last - __first) == __count)
    {
        const bool __result = !__internal::__pattern_any_of(
            std::forward<_ExecutionPolicy>(__exec), __first, __last,
            [&__value, &__pred](const _Tp& __val) { return !__pred(__val, __value); }, __is_vector,
            /*is_parallel*/ std::true_type());
        return __result ? __first : __last;
    }
    else
    {
        return __internal::__except_handler([&__exec, __first, __last, __count, &__value, __pred, __is_vector]() {
            return __internal::__parallel_find(
                std::forward<_ExecutionPolicy>(__exec), __first, __last,
                [__last, __count, &__value, __pred, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) {
                    return __internal::__find_subrange(__i, __j, __last, __count, __value, __pred, __is_vector);
                },
                std::less<typename std::iterator_traits<_RandomAccessIterator>::difference_type>(), /*is_first=*/true);
        });
    }
}

//------------------------------------------------------------------------
// copy_n
//------------------------------------------------------------------------

template <class _ForwardIterator, class _Size, class _OutputIterator>
_OutputIterator
__brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /*vector=*/std::false_type) noexcept
{
    return std::copy_n(__first, __n, __result);
}

template <class _ForwardIterator, class _Size, class _OutputIterator>
_OutputIterator
__brick_copy_n(_ForwardIterator __first, _Size __n, _OutputIterator __result, /*vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_assign(
        __first, __n, __result, [](_ForwardIterator __first, _OutputIterator __result) { *__result = *__first; });
}

//------------------------------------------------------------------------
// copy
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
             /*vector=*/std::false_type) noexcept
{
    return std::copy(__first, __last, __result);
}

template <class _RandomAccessIterator, class _OutputIterator>
_OutputIterator
__brick_copy(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result,
             /*vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_assign(
        __first, __last - __first, __result,
        [](_RandomAccessIterator __first, _OutputIterator __result) { *__result = *__first; });
}

//------------------------------------------------------------------------
// move
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_move(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
             /*vector=*/std::false_type) noexcept
{
    return std::move(__first, __last, __result);
}

template <class _RandomAccessIterator, class _OutputIterator>
_OutputIterator
__brick_move(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator __result,
             /*vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_assign(
        __first, __last - __first, __result,
        [](_RandomAccessIterator __first, _OutputIterator __result) { *__result = std::move(*__first); });
}

struct __brick_move_destroy
{
    template <typename _Iterator, typename _OutputIterator>
    _OutputIterator
    operator()(_Iterator __first, _Iterator __last, _OutputIterator __result, /*vec*/ std::true_type) const
    {
        using _IteratorValueType = typename std::iterator_traits<_Iterator>::value_type;

        return __unseq_backend::__simd_assign(__first, __last - __first, __result,
                                              [](_Iterator __first, _OutputIterator __result) {
                                                  *__result = std::move(*__first);
                                                  (*__first).~_IteratorValueType();
                                              });
    }

    template <typename _Iterator, typename _OutputIterator>
    _OutputIterator
    operator()(_Iterator __first, _Iterator __last, _OutputIterator __result, /*vec*/ std::false_type) const
    {
        using _IteratorValueType = typename std::iterator_traits<_Iterator>::value_type;

        for (; __first != __last; ++__first, ++__result)
        {
            *__result = std::move(*__first);
            (*__first).~_IteratorValueType();
        }
        return __result;
    }
};

//------------------------------------------------------------------------
// swap_ranges
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
                    /*vector=*/std::false_type) noexcept
{
    return std::swap_ranges(__first, __last, __result);
}

template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_swap_ranges(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
                    /*vector=*/std::true_type) noexcept
{
    using std::iter_swap;
    return __unseq_backend::__simd_assign(__first, __last - __first, __result,
                                          iter_swap<_ForwardIterator, _OutputIterator>);
}

//------------------------------------------------------------------------
// copy_if
//------------------------------------------------------------------------
template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
_OutputIterator
__brick_copy_if(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _UnaryPredicate __pred,
                /*vector=*/std::false_type) noexcept
{
    return std::copy_if(__first, __last, __result, __pred);
}

template <class _ForwardIterator, class _OutputIterator, class _UnaryPredicate>
_OutputIterator
__brick_copy_if(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, _UnaryPredicate __pred,
                /*vector=*/std::true_type) noexcept
{
#if (_PSTL_MONOTONIC_PRESENT)
    return __unseq_backend::__simd_copy_if(__first, __last - __first, __result, __pred);
#else
    return std::copy_if(__first, __last, __result, __pred);
#endif
}

// TODO: Try to use transform_reduce for combining __brick_copy_if_phase1 on IsVector.
template <class _DifferenceType, class _ForwardIterator, class _UnaryPredicate>
std::pair<_DifferenceType, _DifferenceType>
__brick_calc_mask_1(_ForwardIterator __first, _ForwardIterator __last, bool* __restrict __mask, _UnaryPredicate __pred,
                    /*vector=*/std::false_type) noexcept
{
    auto __count_true = _DifferenceType(0);
    auto __size = __last - __first;

    static_assert(__is_random_access_iterator<_ForwardIterator>::value,
                  "Pattern-brick error. Should be a random access iterator.");

    for (; __first != __last; ++__first, ++__mask)
    {
        *__mask = __pred(*__first);
        if (*__mask)
        {
            ++__count_true;
        }
    }
    return std::make_pair(__count_true, __size - __count_true);
}

template <class _DifferenceType, class _RandomAccessIterator, class _UnaryPredicate>
std::pair<_DifferenceType, _DifferenceType>
__brick_calc_mask_1(_RandomAccessIterator __first, _RandomAccessIterator __last, bool* __mask, _UnaryPredicate __pred,
                    /*vector=*/std::true_type) noexcept
{
    auto __result = __unseq_backend::__simd_calc_mask_1(__first, __last - __first, __mask, __pred);
    return std::make_pair(__result, (__last - __first) - __result);
}

template <class _ForwardIterator, class _OutputIterator, class _Assigner>
void
__brick_copy_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result, bool* __mask,
                     _Assigner __assigner, /*vector=*/std::false_type) noexcept
{
    for (; __first != __last; ++__first, ++__mask)
    {
        if (*__mask)
        {
            __assigner(__first, __result);
            ++__result;
        }
    }
}

template <class _ForwardIterator, class _OutputIterator, class _Assigner>
void
__brick_copy_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
                     bool* __restrict __mask, _Assigner __assigner, /*vector=*/std::true_type) noexcept
{
#if (_PSTL_MONOTONIC_PRESENT)
    __unseq_backend::__simd_copy_by_mask(__first, __last - __first, __result, __mask, __assigner);
#else
    __internal::__brick_copy_by_mask(__first, __last, __result, __mask, __assigner, std::false_type());
#endif
}

template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2>
void
__brick_partition_by_mask(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator1 __out_true,
                          _OutputIterator2 __out_false, bool* __mask, /*vector=*/std::false_type) noexcept
{
    for (; __first != __last; ++__first, ++__mask)
    {
        if (*__mask)
        {
            *__out_true = *__first;
            ++__out_true;
        }
        else
        {
            *__out_false = *__first;
            ++__out_false;
        }
    }
}

template <class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2>
void
__brick_partition_by_mask(_RandomAccessIterator __first, _RandomAccessIterator __last, _OutputIterator1 __out_true,
                          _OutputIterator2 __out_false, bool* __mask, /*vector=*/std::true_type) noexcept
{
#if (_PSTL_MONOTONIC_PRESENT)
    __unseq_backend::__simd_partition_by_mask(__first, __last - __first, __out_true, __out_false, __mask);
#else
    __internal::__brick_partition_by_mask(__first, __last, __out_true, __out_false, __mask, std::false_type());
#endif
}

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _UnaryPredicate, class _IsVector>
_OutputIterator
__pattern_copy_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
                  _UnaryPredicate __pred, _IsVector __is_vector, /*parallel=*/std::false_type) noexcept
{
    return __internal::__brick_copy_if(__first, __last, __result, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _UnaryPredicate,
          class _IsVector>
_OutputIterator
__pattern_copy_if(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
                  _OutputIterator __result, _UnaryPredicate __pred, _IsVector __is_vector, /*parallel=*/std::true_type)
{
    typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
    const _DifferenceType __n = __last - __first;
    if (_DifferenceType(1) < __n)
    {
        __par_backend::__buffer<bool> __mask_buf(__n);
        return __internal::__except_handler([&__exec, __n, __first, __result, __is_vector, __pred, &__mask_buf]() {
            bool* __mask = __mask_buf.get();
            _DifferenceType __m{};
            __par_backend::__parallel_strict_scan(
                std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0),
                [=](_DifferenceType __i, _DifferenceType __len) { // Reduce
                    return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len),
                                                                            __mask + __i, __pred, __is_vector)
                        .first;
                },
                std::plus<_DifferenceType>(),                                                // Combine
                [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan
                    __internal::__brick_copy_by_mask(
                        __first + __i, __first + (__i + __len), __result + __initial, __mask + __i,
                        [](_RandomAccessIterator __x, _OutputIterator __z) { *__z = *__x; }, __is_vector);
                },
                [&__m](_DifferenceType __total) { __m = __total; });
            return __result + __m;
        });
    }
    // trivial sequence - use serial algorithm
    return __internal::__brick_copy_if(__first, __last, __result, __pred, __is_vector);
}

//------------------------------------------------------------------------
// count
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Predicate>
typename std::iterator_traits<_ForwardIterator>::difference_type
__brick_count(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
              /* is_vector = */ std::true_type) noexcept
{
    return __unseq_backend::__simd_count(__first, __last - __first, __pred);
}

template <class _ForwardIterator, class _Predicate>
typename std::iterator_traits<_ForwardIterator>::difference_type
__brick_count(_ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
              /* is_vector = */ std::false_type) noexcept
{
    return std::count_if(__first, __last, __pred);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate, class _IsVector>
typename std::iterator_traits<_ForwardIterator>::difference_type
__pattern_count(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
                /* is_parallel */ std::false_type, _IsVector __is_vector) noexcept
{
    return __internal::__brick_count(__first, __last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Predicate, class _IsVector>
typename std::iterator_traits<_ForwardIterator>::difference_type
__pattern_count(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Predicate __pred,
                /* is_parallel */ std::true_type, _IsVector __is_vector)
{
    typedef typename std::iterator_traits<_ForwardIterator>::difference_type _SizeType;
    return __internal::__except_handler([&]() {
        return __par_backend::__parallel_reduce(
            std::forward<_ExecutionPolicy>(__exec), __first, __last, _SizeType(0),
            [__pred, __is_vector](_ForwardIterator __begin, _ForwardIterator __end, _SizeType __value) -> _SizeType {
                return __value + __internal::__brick_count(__begin, __end, __pred, __is_vector);
            },
            std::plus<_SizeType>());
    });
}

//------------------------------------------------------------------------
// unique
//------------------------------------------------------------------------

template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator
__brick_unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
               /*is_vector=*/std::false_type) noexcept
{
    return std::unique(__first, __last, __pred);
}

template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator
__brick_unique(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
               /*is_vector=*/std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial");
    return std::unique(__first, __last, __pred);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate, class _IsVector>
_ForwardIterator
__pattern_unique(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
                 _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_unique(__first, __last, __pred, __is_vector);
}

// That function is shared between two algorithms - remove_if (__pattern_remove_if) and unique (pattern unique). But a mask calculation is different.
// So, a caller passes _CalcMask brick into remove_elements.
template <class _ExecutionPolicy, class _ForwardIterator, class _CalcMask, class _IsVector>
_ForwardIterator
__remove_elements(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _CalcMask __calc_mask,
                  _IsVector __is_vector)
{
    typedef typename std::iterator_traits<_ForwardIterator>::difference_type _DifferenceType;
    typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp;
    _DifferenceType __n = __last - __first;
    __par_backend::__buffer<bool> __mask_buf(__n);
    // 1. find a first iterator that should be removed
    return __internal::__except_handler([&]() {
        bool* __mask = __mask_buf.get();
        _DifferenceType __min = __par_backend::__parallel_reduce(
            std::forward<_ExecutionPolicy>(__exec), _DifferenceType(0), __n, __n,
            [__first, __mask, &__calc_mask, __is_vector](_DifferenceType __i, _DifferenceType __j,
                                                         _DifferenceType __local_min) -> _DifferenceType {
                // Create mask
                __calc_mask(__mask + __i, __mask + __j, __first + __i);

                // if minimum was found in a previous range we shouldn't do anymore
                if (__local_min < __i)
                {
                    return __local_min;
                }
                // find first iterator that should be removed
                bool* __result = __internal::__brick_find_if(__mask + __i, __mask + __j,
                                                             [](bool __val) { return !__val; }, __is_vector);
                if (__result - __mask == __j)
                {
                    return __local_min;
                }
                return std::min(__local_min, _DifferenceType(__result - __mask));
            },
            [](_DifferenceType __local_min1, _DifferenceType __local_min2) -> _DifferenceType {
                return std::min(__local_min1, __local_min2);
            });

        // No elements to remove - exit
        if (__min == __n)
        {
            return __last;
        }
        __n -= __min;
        __first += __min;

        __par_backend::__buffer<_Tp> __buf(__n);
        _Tp* __result = __buf.get();
        __mask += __min;
        _DifferenceType __m{};
        // 2. Elements that doesn't satisfy pred are moved to result
        __par_backend::__parallel_strict_scan(
            std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0),
            [__mask, __is_vector](_DifferenceType __i, _DifferenceType __len) {
                return __internal::__brick_count(__mask + __i, __mask + __i + __len, [](bool __val) { return __val; },
                                                 __is_vector);
            },
            std::plus<_DifferenceType>(),
            [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) {
                __internal::__brick_copy_by_mask(
                    __first + __i, __first + __i + __len, __result + __initial, __mask + __i,
                    [](_ForwardIterator __x, _Tp* __z) {
                        __internal::__invoke_if_else(std::is_trivial<_Tp>(), [&]() { *__z = std::move(*__x); },
                                                     [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); });
                    },
                    __is_vector);
            },
            [&__m](_DifferenceType __total) { __m = __total; });

        // 3. Elements from result are moved to [first, last)
        __par_backend::__parallel_for(
            std::forward<_ExecutionPolicy>(__exec), __result, __result + __m,
            [__result, __first, __is_vector](_Tp* __i, _Tp* __j) {
                __invoke_if_else(
                    std::is_trivial<_Tp>(),
                    [&]() { __brick_move(__i, __j, __first + (__i - __result), __is_vector); },
                    [&]() {
                        __brick_move_destroy()(__i, __j, __first + (__i - __result), __is_vector);
                    });
            });
        return __first + __m;
    });
}

template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate, class _IsVector>
_ForwardIterator
__pattern_unique(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
                 _IsVector __is_vector, /*is_parallel=*/std::true_type) noexcept
{
    typedef typename std::iterator_traits<_ForwardIterator>::reference _ReferenceType;

    if (__first == __last)
    {
        return __last;
    }
    if (__first + 1 == __last || __first + 2 == __last)
    {
        // Trivial sequence - use serial algorithm
        return __internal::__brick_unique(__first, __last, __pred, __is_vector);
    }
    return __internal::__remove_elements(
        std::forward<_ExecutionPolicy>(__exec), ++__first, __last,
        [&__pred, __is_vector](bool* __b, bool* __e, _ForwardIterator __it) {
            __internal::__brick_walk3(
                __b, __e, __it - 1, __it,
                [&__pred](bool& __x, _ReferenceType __y, _ReferenceType __z) { __x = !__pred(__y, __z); }, __is_vector);
        },
        __is_vector);
}

//------------------------------------------------------------------------
// unique_copy
//------------------------------------------------------------------------

template <class _ForwardIterator, class OutputIterator, class _BinaryPredicate>
OutputIterator
__brick_unique_copy(_ForwardIterator __first, _ForwardIterator __last, OutputIterator __result, _BinaryPredicate __pred,
                    /*vector=*/std::false_type) noexcept
{
    return std::unique_copy(__first, __last, __result, __pred);
}

template <class _RandomAccessIterator, class OutputIterator, class _BinaryPredicate>
OutputIterator
__brick_unique_copy(_RandomAccessIterator __first, _RandomAccessIterator __last, OutputIterator __result,
                    _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept
{
#if (_PSTL_MONOTONIC_PRESENT)
    return __unseq_backend::__simd_unique_copy(__first, __last - __first, __result, __pred);
#else
    return std::unique_copy(__first, __last, __result, __pred);
#endif
}

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _BinaryPredicate,
          class _IsVector>
_OutputIterator
__pattern_unique_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result,
                      _BinaryPredicate __pred, _IsVector __is_vector, /*parallel=*/std::false_type) noexcept
{
    return __internal::__brick_unique_copy(__first, __last, __result, __pred, __is_vector);
}

template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
_DifferenceType
__brick_calc_mask_2(_RandomAccessIterator __first, _RandomAccessIterator __last, bool* __restrict __mask,
                    _BinaryPredicate __pred, /*vector=*/std::false_type) noexcept
{
    _DifferenceType __count = 0;
    for (; __first != __last; ++__first, ++__mask)
    {
        *__mask = !__pred(*__first, *(__first - 1));
        __count += *__mask;
    }
    return __count;
}

template <class _DifferenceType, class _RandomAccessIterator, class _BinaryPredicate>
_DifferenceType
__brick_calc_mask_2(_RandomAccessIterator __first, _RandomAccessIterator __last, bool* __restrict __mask,
                    _BinaryPredicate __pred, /*vector=*/std::true_type) noexcept
{
    return __unseq_backend::__simd_calc_mask_2(__first, __last - __first, __mask, __pred);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator, class _BinaryPredicate,
          class _IsVector>
_OutputIterator
__pattern_unique_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
                      _OutputIterator __result, _BinaryPredicate __pred, _IsVector __is_vector,
                      /*parallel=*/std::true_type)
{
    typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
    const _DifferenceType __n = __last - __first;
    if (_DifferenceType(2) < __n)
    {
        __par_backend::__buffer<bool> __mask_buf(__n);
        if (_DifferenceType(2) < __n)
        {
            return __internal::__except_handler([&__exec, __n, __first, __result, __pred, __is_vector, &__mask_buf]() {
                bool* __mask = __mask_buf.get();
                _DifferenceType __m{};
                __par_backend::__parallel_strict_scan(
                    std::forward<_ExecutionPolicy>(__exec), __n, _DifferenceType(0),
                    [=](_DifferenceType __i, _DifferenceType __len) -> _DifferenceType { // Reduce
                        _DifferenceType __extra = 0;
                        if (__i == 0)
                        {
                            // Special boundary case
                            __mask[__i] = true;
                            if (--__len == 0)
                                return 1;
                            ++__i;
                            ++__extra;
                        }
                        return __internal::__brick_calc_mask_2<_DifferenceType>(__first + __i, __first + (__i + __len),
                                                                                __mask + __i, __pred, __is_vector) +
                               __extra;
                    },
                    std::plus<_DifferenceType>(),                                                // Combine
                    [=](_DifferenceType __i, _DifferenceType __len, _DifferenceType __initial) { // Scan
                        // Phase 2 is same as for __pattern_copy_if
                        __internal::__brick_copy_by_mask(
                            __first + __i, __first + (__i + __len), __result + __initial, __mask + __i,
                            [](_RandomAccessIterator __x, _OutputIterator __z) { *__z = *__x; }, __is_vector);
                    },
                    [&__m](_DifferenceType __total) { __m = __total; });
                return __result + __m;
            });
        }
    }
    // trivial sequence - use serial algorithm
    return __internal::__brick_unique_copy(__first, __last, __result, __pred, __is_vector);
}

//------------------------------------------------------------------------
// reverse
//------------------------------------------------------------------------
template <class _BidirectionalIterator>
void
__brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, /*__is_vector=*/std::false_type) noexcept
{
    std::reverse(__first, __last);
}

template <class _BidirectionalIterator>
void
__brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, /*__is_vector=*/std::true_type) noexcept
{
    typedef typename std::iterator_traits<_BidirectionalIterator>::reference _ReferenceType;

    const auto __n = (__last - __first) / 2;
    __unseq_backend::__simd_walk_2(__first, __n, std::reverse_iterator<_BidirectionalIterator>(__last),
                                   [](_ReferenceType __x, _ReferenceType __y) {
                                       using std::swap;
                                       swap(__x, __y);
                                   });
}

// this brick is called in parallel version, so we can use iterator arithmetic
template <class _BidirectionalIterator>
void
__brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, _BidirectionalIterator __d_last,
                /*is_vector=*/std::false_type) noexcept
{
    for (--__d_last; __first != __last; ++__first, --__d_last)
    {
        using std::iter_swap;
        iter_swap(__first, __d_last);
    }
}

// this brick is called in parallel version, so we can use iterator arithmetic
template <class _BidirectionalIterator>
void
__brick_reverse(_BidirectionalIterator __first, _BidirectionalIterator __last, _BidirectionalIterator __d_last,
                /*is_vector=*/std::true_type) noexcept
{
    typedef typename std::iterator_traits<_BidirectionalIterator>::reference _ReferenceType;

    __unseq_backend::__simd_walk_2(__first, __last - __first, std::reverse_iterator<_BidirectionalIterator>(__d_last),
                                   [](_ReferenceType __x, _ReferenceType __y) {
                                       using std::swap;
                                       swap(__x, __y);
                                   });
}

template <class _ExecutionPolicy, class _BidirectionalIterator, class _IsVector>
void
__pattern_reverse(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last,
                  _IsVector _is_vector,
                  /*is_parallel=*/std::false_type) noexcept
{
    __internal::__brick_reverse(__first, __last, _is_vector);
}

template <class _ExecutionPolicy, class _BidirectionalIterator, class _IsVector>
void
__pattern_reverse(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last,
                  _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
    __par_backend::__parallel_for(
        std::forward<_ExecutionPolicy>(__exec), __first, __first + (__last - __first) / 2,
        [__is_vector, __first, __last](_BidirectionalIterator __inner_first, _BidirectionalIterator __inner_last) {
            __internal::__brick_reverse(__inner_first, __inner_last, __last - (__inner_first - __first), __is_vector);
        });
}

//------------------------------------------------------------------------
// reverse_copy
//------------------------------------------------------------------------

template <class _BidirectionalIterator, class _OutputIterator>
_OutputIterator
__brick_reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __d_first,
                     /*is_vector=*/std::false_type) noexcept
{
    return std::reverse_copy(__first, __last, __d_first);
}

template <class _BidirectionalIterator, class _OutputIterator>
_OutputIterator
__brick_reverse_copy(_BidirectionalIterator __first, _BidirectionalIterator __last, _OutputIterator __d_first,
                     /*is_vector=*/std::true_type) noexcept
{
    typedef typename std::iterator_traits<_BidirectionalIterator>::reference _ReferenceType1;
    typedef typename std::iterator_traits<_OutputIterator>::reference _ReferenceType2;

    return __unseq_backend::__simd_walk_2(std::reverse_iterator<_BidirectionalIterator>(__last), __last - __first,
                                          __d_first, [](_ReferenceType1 __x, _ReferenceType2 __y) { __y = __x; });
}

template <class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator, class _IsVector>
_OutputIterator
__pattern_reverse_copy(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last,
                       _OutputIterator __d_first, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_reverse_copy(__first, __last, __d_first, __is_vector);
}

template <class _ExecutionPolicy, class _BidirectionalIterator, class _OutputIterator, class _IsVector>
_OutputIterator
__pattern_reverse_copy(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last,
                       _OutputIterator __d_first, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
    auto __len = __last - __first;
    __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
                                  [__is_vector, __first, __len, __d_first](_BidirectionalIterator __inner_first,
                                                                           _BidirectionalIterator __inner_last) {
                                      __internal::__brick_reverse_copy(__inner_first, __inner_last,
                                                                       __d_first + (__len - (__inner_last - __first)),
                                                                       __is_vector);
                                  });
    return __d_first + __len;
}

//------------------------------------------------------------------------
// rotate
//------------------------------------------------------------------------
template <class _ForwardIterator>
_ForwardIterator
__brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
               /*is_vector=*/std::false_type) noexcept
{
#if _PSTL_CPP11_STD_ROTATE_BROKEN
    std::rotate(__first, __middle, __last);
    return std::next(__first, std::distance(__middle, __last));
#else
    return std::rotate(__first, __middle, __last);
#endif
}

template <class _ForwardIterator>
_ForwardIterator
__brick_rotate(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
               /*is_vector=*/std::true_type) noexcept
{
    auto __n = __last - __first;
    auto __m = __middle - __first;
    const _ForwardIterator __ret = __first + (__last - __middle);

    bool __is_left = (__m <= __n / 2);
    if (!__is_left)
        __m = __n - __m;

    while (__n > 1 && __m > 0)
    {
        using std::iter_swap;
        const auto __m_2 = __m * 2;
        if (__is_left)
        {
            for (; __last - __first >= __m_2; __first += __m)
            {
                __unseq_backend::__simd_assign(__first, __m, __first + __m,
                                               iter_swap<_ForwardIterator, _ForwardIterator>);
            }
        }
        else
        {
            for (; __last - __first >= __m_2; __last -= __m)
            {
                __unseq_backend::__simd_assign(__last - __m, __m, __last - __m_2,
                                               iter_swap<_ForwardIterator, _ForwardIterator>);
            }
        }
        __is_left = !__is_left;
        __m = __n % __m;
        __n = __last - __first;
    }

    return __ret;
}

template <class _ExecutionPolicy, class _ForwardIterator, class _IsVector>
_ForwardIterator
__pattern_rotate(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
                 _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_rotate(__first, __middle, __last, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _IsVector>
_ForwardIterator
__pattern_rotate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle,
                 _ForwardIterator __last, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
    typedef typename std::iterator_traits<_ForwardIterator>::value_type _Tp;
    auto __n = __last - __first;
    auto __m = __middle - __first;
    if (__m <= __n / 2)
    {
        __par_backend::__buffer<_Tp> __buf(__n - __m);
        return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, __is_vector, &__buf]() {
            _Tp* __result = __buf.get();
            __par_backend::__parallel_for(
                std::forward<_ExecutionPolicy>(__exec), __middle, __last,
                [__middle, __result, __is_vector](_ForwardIterator __b, _ForwardIterator __e) {
                    __internal::__brick_uninitialized_move(__b, __e, __result + (__b - __middle), __is_vector);
                });

            __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __middle,
                                          [__last, __middle, __is_vector](_ForwardIterator __b, _ForwardIterator __e) {
                                              __internal::__brick_move(__b, __e, __b + (__last - __middle),
                                                                       __is_vector);
                                          });

            __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + (__n - __m),
                                          [__first, __result, __is_vector](_Tp* __b, _Tp* __e) {
                                              __brick_move_destroy()(
                                                  __b, __e, __first + (__b - __result), __is_vector);
                                          });

            return __first + (__last - __middle);
        });
    }
    else
    {
        __par_backend::__buffer<_Tp> __buf(__m);
        return __internal::__except_handler([&__exec, __n, __m, __first, __middle, __last, __is_vector, &__buf]() {
            _Tp* __result = __buf.get();
            __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __middle,
                                          [__first, __result, __is_vector](_ForwardIterator __b, _ForwardIterator __e) {
                                              __internal::__brick_uninitialized_move(
                                                  __b, __e, __result + (__b - __first), __is_vector);
                                          });

            __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __middle, __last,
                                          [__first, __middle, __is_vector](_ForwardIterator __b, _ForwardIterator __e) {
                                              __internal::__brick_move(__b, __e, __first + (__b - __middle),
                                                                       __is_vector);
                                          });

            __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __result, __result + __m,
                                          [__n, __m, __first, __result, __is_vector](_Tp* __b, _Tp* __e) {
                                              __brick_move_destroy()(
                                                  __b, __e, __first + ((__n - __m) + (__b - __result)), __is_vector);
                                          });

            return __first + (__last - __middle);
        });
    }
}

//------------------------------------------------------------------------
// rotate_copy
//------------------------------------------------------------------------

template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
                    _OutputIterator __result, /*__is_vector=*/std::false_type) noexcept
{
    return std::rotate_copy(__first, __middle, __last, __result);
}

template <class _ForwardIterator, class _OutputIterator>
_OutputIterator
__brick_rotate_copy(_ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
                    _OutputIterator __result, /*__is_vector=*/std::true_type) noexcept
{
    _OutputIterator __res = __internal::__brick_copy(__middle, __last, __result, std::true_type());
    return __internal::__brick_copy(__first, __middle, __res, std::true_type());
}

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _IsVector>
_OutputIterator
__pattern_rotate_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __middle, _ForwardIterator __last,
                      _OutputIterator __result, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_rotate_copy(__first, __middle, __last, __result, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator, class _IsVector>
_OutputIterator
__pattern_rotate_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __middle,
                      _ForwardIterator __last, _OutputIterator __result, _IsVector __is_vector,
                      /*is_parallel=*/std::true_type)
{
    __par_backend::__parallel_for(
        std::forward<_ExecutionPolicy>(__exec), __first, __last,
        [__first, __last, __middle, __result, __is_vector](_ForwardIterator __b, _ForwardIterator __e) {
            if (__b > __middle)
            {
                __internal::__brick_copy(__b, __e, __result + (__b - __middle), __is_vector);
            }
            else
            {
                _OutputIterator __new_result = __result + ((__last - __middle) + (__b - __first));
                if (__e < __middle)
                {
                    __internal::__brick_copy(__b, __e, __new_result, __is_vector);
                }
                else
                {
                    __internal::__brick_copy(__b, __middle, __new_result, __is_vector);
                    __internal::__brick_copy(__middle, __e, __result, __is_vector);
                }
            }
        });
    return __result + (__last - __first);
}

//------------------------------------------------------------------------
// is_partitioned
//------------------------------------------------------------------------

template <class _ForwardIterator, class _UnaryPredicate>
bool
__brick_is_partitioned(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
                       /*is_vector=*/std::false_type) noexcept
{
    return std::is_partitioned(__first, __last, __pred);
}

template <class _ForwardIterator, class _UnaryPredicate>
bool
__brick_is_partitioned(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
                       /*is_vector=*/std::true_type) noexcept
{
    typedef typename std::iterator_traits<_ForwardIterator>::difference_type _SizeType;
    if (__first == __last)
    {
        return true;
    }
    else
    {
        _ForwardIterator __result = __unseq_backend::__simd_first(
            __first, _SizeType(0), __last - __first,
            [&__pred](_ForwardIterator __it, _SizeType __i) { return !__pred(__it[__i]); });
        if (__result == __last)
        {
            return true;
        }
        else
        {
            ++__result;
            return !__unseq_backend::__simd_or(__result, __last - __result, __pred);
        }
    }
}

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
bool
__pattern_is_partitioned(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
                         _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_is_partitioned(__first, __last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
bool
__pattern_is_partitioned(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
                         _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
    if (__first == __last)
    {
        return true;
    }
    else
    {
        return __internal::__except_handler([&]() {
            // State of current range:
            // broken     - current range is not partitioned by pred
            // all_true   - all elements in current range satisfy pred
            // all_false  - all elements in current range don't satisfy pred
            // true_false - elements satisfy pred are placed before elements that don't satisfy pred
            enum _ReduceType
            {
                __not_init = -1,
                __broken,
                __all_true,
                __all_false,
                __true_false
            };
            _ReduceType __init = __not_init;

            // Array with states that we'll have when state from the left branch is merged with state from the right branch.
            // State is calculated by formula: new_state = table[left_state * 4 + right_state]
            _ReduceType __table[] = {__broken,     __broken,     __broken,     __broken, __broken,    __all_true,
                                     __true_false, __true_false, __broken,     __broken, __all_false, __broken,
                                     __broken,     __broken,     __true_false, __broken};

            __init = __par_backend::__parallel_reduce(
                std::forward<_ExecutionPolicy>(__exec), __first, __last, __init,
                [&__pred, &__table, __is_vector](_ForwardIterator __i, _ForwardIterator __j,
                                                 _ReduceType __value) -> _ReduceType {
                    if (__value == __broken)
                    {
                        return __broken;
                    }
                    _ReduceType __res = __not_init;
                    // if first element satisfy pred
                    if (__pred(*__i))
                    {
                        // find first element that don't satisfy pred
                        _ForwardIterator __x =
                            __internal::__brick_find_if(__i + 1, __j, std::not_fn(__pred), __is_vector);
                        if (__x != __j)
                        {
                            // find first element after "x" that satisfy pred
                            _ForwardIterator __y = __internal::__brick_find_if(__x + 1, __j, __pred, __is_vector);
                            // if it was found then range isn't partitioned by pred
                            if (__y != __j)
                            {
                                return __broken;
                            }
                            else
                            {
                                __res = __true_false;
                            }
                        }
                        else
                        {
                            __res = __all_true;
                        }
                    }
                    else
                    { // if first element doesn't satisfy pred
                        // then we should find the first element that satisfy pred.
                        // If we found it then range isn't partitioned by pred
                        if (__internal::__brick_find_if(__i + 1, __j, __pred, __is_vector) != __j)
                        {
                            return __broken;
                        }
                        else
                        {
                            __res = __all_false;
                        }
                    }
                    // if we have value from left range then we should calculate the result
                    return (__value == -1) ? __res : __table[__value * 4 + __res];
                },

                [&__table](_ReduceType __val1, _ReduceType __val2) -> _ReduceType {
                    if (__val1 == __broken || __val2 == __broken)
                    {
                        return __broken;
                    }
                    // calculate the result for new big range
                    return __table[__val1 * 4 + __val2];
                });
            return __init != __broken;
        });
    }
}

//------------------------------------------------------------------------
// partition
//------------------------------------------------------------------------

template <class _ForwardIterator, class _UnaryPredicate>
_ForwardIterator
__brick_partition(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
                  /*is_vector=*/std::false_type) noexcept
{
    return std::partition(__first, __last, __pred);
}

template <class _ForwardIterator, class _UnaryPredicate>
_ForwardIterator
__brick_partition(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
                  /*is_vector=*/std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial");
    return std::partition(__first, __last, __pred);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
_ForwardIterator
__pattern_partition(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
                    _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_partition(__first, __last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
_ForwardIterator
__pattern_partition(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
                    _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{

    // partitioned range: elements before pivot satisfy pred (true part),
    //                    elements after pivot don't satisfy pred (false part)
    struct _PartitionRange
    {
        _ForwardIterator __begin;
        _ForwardIterator __pivot;
        _ForwardIterator __end;
    };

    return __internal::__except_handler([&]() {
        _PartitionRange __init{__last, __last, __last};

        // lambda for merging two partitioned ranges to one partitioned range
        auto __reductor = [&__exec, __is_vector](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange {
            auto __size1 = __val1.__end - __val1.__pivot;
            auto __size2 = __val2.__pivot - __val2.__begin;
            auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin);

            // if all elements in left range satisfy pred then we can move new pivot to pivot of right range
            if (__val1.__end == __val1.__pivot)
            {
                return {__new_begin, __val2.__pivot, __val2.__end};
            }
            // if true part of right range greater than false part of left range
            // then we should swap the false part of left range and last part of true part of right range
            else if (__size2 > __size1)
            {
                __par_backend::__parallel_for(
                    std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size1,
                    [__val1, __val2, __size1, __is_vector](_ForwardIterator __i, _ForwardIterator __j) {
                        __internal::__brick_swap_ranges(__i, __j, (__val2.__pivot - __size1) + (__i - __val1.__pivot),
                                                        __is_vector);
                    });
                return {__new_begin, __val2.__pivot - __size1, __val2.__end};
            }
            // else we should swap the first part of false part of left range and true part of right range
            else
            {
                __par_backend::__parallel_for(
                    std::forward<_ExecutionPolicy>(__exec), __val1.__pivot, __val1.__pivot + __size2,
                    [__val1, __val2, __is_vector](_ForwardIterator __i, _ForwardIterator __j) {
                        __internal::__brick_swap_ranges(__i, __j, __val2.__begin + (__i - __val1.__pivot), __is_vector);
                    });
                return {__new_begin, __val1.__pivot + __size2, __val2.__end};
            }
        };

        _PartitionRange __result = __par_backend::__parallel_reduce(
            std::forward<_ExecutionPolicy>(__exec), __first, __last, __init,
            [__pred, __is_vector, __reductor](_ForwardIterator __i, _ForwardIterator __j,
                                              _PartitionRange __value) -> _PartitionRange {
                //1. serial partition
                _ForwardIterator __pivot = __internal::__brick_partition(__i, __j, __pred, __is_vector);

                // 2. merging of two ranges (left and right respectively)
                return __reductor(__value, {__i, __pivot, __j});
            },
            __reductor);
        return __result.__pivot;
    });
}

//------------------------------------------------------------------------
// stable_partition
//------------------------------------------------------------------------

template <class _BidirectionalIterator, class _UnaryPredicate>
_BidirectionalIterator
__brick_stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred,
                         /*__is_vector=*/std::false_type) noexcept
{
    return std::stable_partition(__first, __last, __pred);
}

template <class _BidirectionalIterator, class _UnaryPredicate>
_BidirectionalIterator
__brick_stable_partition(_BidirectionalIterator __first, _BidirectionalIterator __last, _UnaryPredicate __pred,
                         /*__is_vector=*/std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial");
    return std::stable_partition(__first, __last, __pred);
}

template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate, class _IsVector>
_BidirectionalIterator
__pattern_stable_partition(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __last,
                           _UnaryPredicate __pred, _IsVector __is_vector,
                           /*is_parallelization=*/std::false_type) noexcept
{
    return __internal::__brick_stable_partition(__first, __last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _BidirectionalIterator, class _UnaryPredicate, class _IsVector>
_BidirectionalIterator
__pattern_stable_partition(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __last,
                           _UnaryPredicate __pred, _IsVector __is_vector,
                           /*is_parallelization=*/std::true_type) noexcept
{
    // partitioned range: elements before pivot satisfy pred (true part),
    //                    elements after pivot don't satisfy pred (false part)
    struct _PartitionRange
    {
        _BidirectionalIterator __begin;
        _BidirectionalIterator __pivot;
        _BidirectionalIterator __end;
    };

    return __internal::__except_handler([&]() {
        _PartitionRange __init{__last, __last, __last};

        // lambda for merging two partitioned ranges to one partitioned range
        auto __reductor = [__is_vector](_PartitionRange __val1, _PartitionRange __val2) -> _PartitionRange {
            auto __size1 = __val1.__end - __val1.__pivot;
            auto __new_begin = __val2.__begin - (__val1.__end - __val1.__begin);

            // if all elements in left range satisfy pred then we can move new pivot to pivot of right range
            if (__val1.__end == __val1.__pivot)
            {
                return {__new_begin, __val2.__pivot, __val2.__end};
            }
            // if true part of right range greater than false part of left range
            // then we should swap the false part of left range and last part of true part of right range
            else
            {
                __internal::__brick_rotate(__val1.__pivot, __val2.__begin, __val2.__pivot, __is_vector);
                return {__new_begin, __val2.__pivot - __size1, __val2.__end};
            }
        };

        _PartitionRange __result = __par_backend::__parallel_reduce(
            std::forward<_ExecutionPolicy>(__exec), __first, __last, __init,
            [&__pred, __is_vector, __reductor](_BidirectionalIterator __i, _BidirectionalIterator __j,
                                               _PartitionRange __value) -> _PartitionRange {
                //1. serial stable_partition
                _BidirectionalIterator __pivot = __internal::__brick_stable_partition(__i, __j, __pred, __is_vector);

                // 2. merging of two ranges (left and right respectively)
                return __reductor(__value, {__i, __pivot, __j});
            },
            __reductor);
        return __result.__pivot;
    });
}

//------------------------------------------------------------------------
// partition_copy
//------------------------------------------------------------------------

template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
std::pair<_OutputIterator1, _OutputIterator2>
__brick_partition_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator1 __out_true,
                       _OutputIterator2 __out_false, _UnaryPredicate __pred, /*is_vector=*/std::false_type) noexcept
{
    return std::partition_copy(__first, __last, __out_true, __out_false, __pred);
}

template <class _ForwardIterator, class _OutputIterator1, class _OutputIterator2, class _UnaryPredicate>
std::pair<_OutputIterator1, _OutputIterator2>
__brick_partition_copy(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator1 __out_true,
                       _OutputIterator2 __out_false, _UnaryPredicate __pred, /*is_vector=*/std::true_type) noexcept
{
#if (_PSTL_MONOTONIC_PRESENT)
    return __unseq_backend::__simd_partition_copy(__first, __last - __first, __out_true, __out_false, __pred);
#else
    return std::partition_copy(__first, __last, __out_true, __out_false, __pred);
#endif
}

template <class _ExecutionPolicy, class _ForwardIterator, class _OutputIterator1, class _OutputIterator2,
          class _UnaryPredicate, class _IsVector>
std::pair<_OutputIterator1, _OutputIterator2>
__pattern_partition_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last,
                         _OutputIterator1 __out_true, _OutputIterator2 __out_false, _UnaryPredicate __pred,
                         _IsVector __is_vector, /*is_parallelization=*/std::false_type) noexcept
{
    return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _OutputIterator1, class _OutputIterator2,
          class _UnaryPredicate, class _IsVector>
std::pair<_OutputIterator1, _OutputIterator2>
__pattern_partition_copy(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
                         _OutputIterator1 __out_true, _OutputIterator2 __out_false, _UnaryPredicate __pred,
                         _IsVector __is_vector, /*is_parallelization=*/std::true_type)
{
    typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _DifferenceType;
    typedef std::pair<_DifferenceType, _DifferenceType> _ReturnType;
    const _DifferenceType __n = __last - __first;
    if (_DifferenceType(1) < __n)
    {
        __par_backend::__buffer<bool> __mask_buf(__n);
        return __internal::__except_handler([&__exec, __n, __first, __out_true, __out_false, __is_vector, __pred,
                                             &__mask_buf]() {
            bool* __mask = __mask_buf.get();
            _ReturnType __m{};
            __par_backend::__parallel_strict_scan(
                std::forward<_ExecutionPolicy>(__exec), __n, std::make_pair(_DifferenceType(0), _DifferenceType(0)),
                [=](_DifferenceType __i, _DifferenceType __len) { // Reduce
                    return __internal::__brick_calc_mask_1<_DifferenceType>(__first + __i, __first + (__i + __len),
                                                                            __mask + __i, __pred, __is_vector);
                },
                [](const _ReturnType& __x, const _ReturnType& __y) -> _ReturnType {
                    return std::make_pair(__x.first + __y.first, __x.second + __y.second);
                },                                                                       // Combine
                [=](_DifferenceType __i, _DifferenceType __len, _ReturnType __initial) { // Scan
                    __internal::__brick_partition_by_mask(__first + __i, __first + (__i + __len),
                                                          __out_true + __initial.first, __out_false + __initial.second,
                                                          __mask + __i, __is_vector);
                },
                [&__m](_ReturnType __total) { __m = __total; });
            return std::make_pair(__out_true + __m.first, __out_false + __m.second);
        });
    }
    // trivial sequence - use serial algorithm
    return __internal::__brick_partition_copy(__first, __last, __out_true, __out_false, __pred, __is_vector);
}

//------------------------------------------------------------------------
// sort
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector,
          class _IsMoveConstructible>
void
__pattern_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
               _IsVector /*is_vector*/, /*is_parallel=*/std::false_type, _IsMoveConstructible) noexcept
{
    std::sort(__first, __last, __comp);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
               _IsVector /*is_vector*/, /*is_parallel=*/std::true_type, /*is_move_constructible=*/std::true_type)
{
    __internal::__except_handler([&]() {
        __par_backend::__parallel_stable_sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
                                              [](_RandomAccessIterator __first, _RandomAccessIterator __last,
                                                 _Compare __comp) { std::sort(__first, __last, __comp); });
    });
}

//------------------------------------------------------------------------
// stable_sort
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_stable_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
                      _IsVector /*is_vector*/, /*is_parallel=*/std::false_type) noexcept
{
    std::stable_sort(__first, __last, __comp);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_stable_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
                      _Compare __comp, _IsVector /*is_vector*/, /*is_parallel=*/std::true_type)
{
    __internal::__except_handler([&]() {
        __par_backend::__parallel_stable_sort(std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
                                              [](_RandomAccessIterator __first, _RandomAccessIterator __last,
                                                 _Compare __comp) { std::stable_sort(__first, __last, __comp); });
    });
}

//------------------------------------------------------------------------
// partial_sort
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_partial_sort(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __middle,
                       _RandomAccessIterator __last, _Compare __comp, _IsVector,
                       /*is_parallel=*/std::false_type) noexcept
{
    std::partial_sort(__first, __middle, __last, __comp);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_partial_sort(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __middle,
                       _RandomAccessIterator __last, _Compare __comp, _IsVector, /*is_parallel=*/std::true_type)
{
    const auto __n = __middle - __first;
    if (__n == 0)
        return;

    __internal::__except_handler([&]() {
        __par_backend::__parallel_stable_sort(
            std::forward<_ExecutionPolicy>(__exec), __first, __last, __comp,
            [__n](_RandomAccessIterator __begin, _RandomAccessIterator __end, _Compare __comp) {
                if (__n < __end - __begin)
                    std::partial_sort(__begin, __begin + __n, __end, __comp);
                else
                    std::sort(__begin, __end, __comp);
            },
            __n);
    });
}

//------------------------------------------------------------------------
// partial_sort_copy
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare, class _IsVector>
_RandomAccessIterator
__pattern_partial_sort_copy(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last,
                            _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp, _IsVector,
                            /*is_parallel=*/std::false_type) noexcept
{
    return std::partial_sort_copy(__first, __last, __d_first, __d_last, __comp);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _RandomAccessIterator, class _Compare, class _IsVector>
_RandomAccessIterator
__pattern_partial_sort_copy(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
                            _RandomAccessIterator __d_first, _RandomAccessIterator __d_last, _Compare __comp,
                            _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
    if (__last == __first || __d_last == __d_first)
    {
        return __d_first;
    }
    auto __n1 = __last - __first;
    auto __n2 = __d_last - __d_first;
    return __internal::__except_handler([&]() {
        if (__n2 >= __n1)
        {
            __par_backend::__parallel_stable_sort(
                std::forward<_ExecutionPolicy>(__exec), __d_first, __d_first + __n1, __comp,
                [__first, __d_first, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j,
                                                  _Compare __comp) {
                    _ForwardIterator __i1 = __first + (__i - __d_first);
                    _ForwardIterator __j1 = __first + (__j - __d_first);

                // 1. Copy elements from input to output
#    if !_PSTL_ICC_18_OMP_SIMD_BROKEN
                    __internal::__brick_copy(__i1, __j1, __i, __is_vector);
#    else
                    std::copy(__i1, __j1, __i);
#    endif
                    // 2. Sort elements in output sequence
                    std::sort(__i, __j, __comp);
                },
                __n1);
            return __d_first + __n1;
        }
        else
        {
            typedef typename std::iterator_traits<_ForwardIterator>::value_type _T1;
            typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _T2;
            __par_backend::__buffer<_T1> __buf(__n1);
            _T1* __r = __buf.get();

            __par_backend::__parallel_stable_sort(std::forward<_ExecutionPolicy>(__exec), __r, __r + __n1, __comp,
                                                  [__n2, __first, __r](_T1* __i, _T1* __j, _Compare __comp) {
                                                      _ForwardIterator __it = __first + (__i - __r);

                                                      // 1. Copy elements from input to raw memory
                                                      for (_T1* __k = __i; __k != __j; ++__k, ++__it)
                                                      {
                                                          ::new (__k) _T2(*__it);
                                                      }

                                                      // 2. Sort elements in temporary __buffer
                                                      if (__n2 < __j - __i)
                                                          std::partial_sort(__i, __i + __n2, __j, __comp);
                                                      else
                                                          std::sort(__i, __j, __comp);
                                                  },
                                                  __n2);

            // 3. Move elements from temporary __buffer to output
            __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __r, __r + __n2,
                                          [__r, __d_first, __is_vector](_T1* __i, _T1* __j) {
                                              __brick_move_destroy()(
                                                  __i, __j, __d_first + (__i - __r), __is_vector);
                                          });
            __par_backend::__parallel_for(
                std::forward<_ExecutionPolicy>(__exec), __r + __n2, __r + __n1,
                [__is_vector](_T1* __i, _T1* __j) { __brick_destroy(__i, __j, __is_vector); });

            return __d_first + __n2;
        }
    });
}

//------------------------------------------------------------------------
// adjacent_find
//------------------------------------------------------------------------
template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator
__brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
                      /* IsVector = */ std::true_type, bool __or_semantic) noexcept
{
    return __unseq_backend::__simd_adjacent_find(__first, __last, __pred, __or_semantic);
}

template <class _ForwardIterator, class _BinaryPredicate>
_ForwardIterator
__brick_adjacent_find(_ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
                      /* IsVector = */ std::false_type, bool) noexcept
{
    return std::adjacent_find(__first, __last, __pred);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _BinaryPredicate, class _IsVector>
_ForwardIterator
__pattern_adjacent_find(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _BinaryPredicate __pred,
                        /* is_parallel */ std::false_type, _IsVector __is_vector, bool __or_semantic) noexcept
{
    return __internal::__brick_adjacent_find(__first, __last, __pred, __is_vector, __or_semantic);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _BinaryPredicate, class _IsVector>
_RandomAccessIterator
__pattern_adjacent_find(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
                        _BinaryPredicate __pred, /* is_parallel */ std::true_type, _IsVector __is_vector,
                        bool __or_semantic)
{
    if (__last - __first < 2)
        return __last;

    return __internal::__except_handler([&]() {
        return __par_backend::__parallel_reduce(
            std::forward<_ExecutionPolicy>(__exec), __first, __last, __last,
            [__last, __pred, __is_vector, __or_semantic](_RandomAccessIterator __begin, _RandomAccessIterator __end,
                                                         _RandomAccessIterator __value) -> _RandomAccessIterator {
                // TODO: investigate performance benefits from the use of shared variable for the result,
                // checking (compare_and_swap idiom) its __value at __first.
                if (__or_semantic && __value < __last)
                { //found
                    __par_backend::__cancel_execution();
                    return __value;
                }

                if (__value > __begin)
                {
                    // modify __end to check the predicate on the boundary __values;
                    // TODO: to use a custom range with boundaries overlapping
                    // TODO: investigate what if we remove "if" below and run algorithm on range [__first, __last-1)
                    // then check the pair [__last-1, __last)
                    if (__end != __last)
                        ++__end;

                    //correct the global result iterator if the "brick" returns a local "__last"
                    const _RandomAccessIterator __res =
                        __internal::__brick_adjacent_find(__begin, __end, __pred, __is_vector, __or_semantic);
                    if (__res < __end)
                        __value = __res;
                }
                return __value;
            },
            [](_RandomAccessIterator __x, _RandomAccessIterator __y) -> _RandomAccessIterator {
                return __x < __y ? __x : __y;
            } //reduce a __value
        );
    });
}

//------------------------------------------------------------------------
// nth_element
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_nth_element(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __nth,
                      _RandomAccessIterator __last, _Compare __comp, _IsVector,
                      /*is_parallel=*/std::false_type) noexcept
{
    std::nth_element(__first, __nth, __last, __comp);
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
void
__pattern_nth_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __nth,
                      _RandomAccessIterator __last, _Compare __comp, _IsVector __is_vector,
                      /*is_parallel=*/std::true_type) noexcept
{
    if (__first == __last || __nth == __last)
    {
        return;
    }

    using std::iter_swap;
    typedef typename std::iterator_traits<_RandomAccessIterator>::value_type _Tp;
    _RandomAccessIterator __x;
    do
    {
        __x = __internal::__pattern_partition(std::forward<_ExecutionPolicy>(__exec), __first + 1, __last,
                                              [&__comp, __first](const _Tp& __x) { return __comp(__x, *__first); },
                                              __is_vector,
                                              /*is_parallel=*/std::true_type());
        --__x;
        if (__x != __first)
        {
            iter_swap(__first, __x);
        }
        // if x > nth then our new range for partition is [first, x)
        if (__x - __nth > 0)
        {
            __last = __x;
        }
        // if x < nth then our new range for partition is [x, last)
        else if (__x - __nth < 0)
        {
            // if *x == *nth then we can start new partition with x+1
            if (!__comp(*__nth, *__x) && !__comp(*__x, *__nth))
            {
                ++__x;
            }
            else
            {
                iter_swap(__nth, __x);
            }
            __first = __x;
        }
    } while (__x != __nth);
}

//------------------------------------------------------------------------
// fill, fill_n
//------------------------------------------------------------------------
template <class _ForwardIterator, class _Tp>
void
__brick_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value,
             /* __is_vector = */ std::true_type) noexcept
{
    __unseq_backend::__simd_fill_n(__first, __last - __first, __value);
}

template <class _ForwardIterator, class _Tp>
void
__brick_fill(_ForwardIterator __first, _ForwardIterator __last, const _Tp& __value,
             /* __is_vector = */ std::false_type) noexcept
{
    std::fill(__first, __last, __value);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _IsVector>
void
__pattern_fill(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value,
               /*is_parallel=*/std::false_type, _IsVector __is_vector) noexcept
{
    __internal::__brick_fill(__first, __last, __value, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Tp, class _IsVector>
_ForwardIterator
__pattern_fill(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, const _Tp& __value,
               /*is_parallel=*/std::true_type, _IsVector __is_vector)
{
    return __internal::__except_handler([&__exec, __first, __last, &__value, __is_vector]() {
        __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
                                      [&__value, __is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
                                          __internal::__brick_fill(__begin, __end, __value, __is_vector);
                                      });
        return __last;
    });
}

template <class _OutputIterator, class _Size, class _Tp>
_OutputIterator
__brick_fill_n(_OutputIterator __first, _Size __count, const _Tp& __value, /* __is_vector = */ std::true_type) noexcept
{
    return __unseq_backend::__simd_fill_n(__first, __count, __value);
}

template <class _OutputIterator, class _Size, class _Tp>
_OutputIterator
__brick_fill_n(_OutputIterator __first, _Size __count, const _Tp& __value, /* __is_vector = */ std::false_type) noexcept
{
    return std::fill_n(__first, __count, __value);
}

template <class _ExecutionPolicy, class _OutputIterator, class _Size, class _Tp, class _IsVector>
_OutputIterator
__pattern_fill_n(_ExecutionPolicy&&, _OutputIterator __first, _Size __count, const _Tp& __value,
                 /*is_parallel=*/std::false_type, _IsVector __is_vector) noexcept
{
    return __internal::__brick_fill_n(__first, __count, __value, __is_vector);
}

template <class _ExecutionPolicy, class _OutputIterator, class _Size, class _Tp, class _IsVector>
_OutputIterator
__pattern_fill_n(_ExecutionPolicy&& __exec, _OutputIterator __first, _Size __count, const _Tp& __value,
                 /*is_parallel=*/std::true_type, _IsVector __is_vector)
{
    return __internal::__pattern_fill(std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __value,
                                      std::true_type(), __is_vector);
}

//------------------------------------------------------------------------
// generate, generate_n
//------------------------------------------------------------------------
template <class _RandomAccessIterator, class _Generator>
void
__brick_generate(_RandomAccessIterator __first, _RandomAccessIterator __last, _Generator __g,
                 /* is_vector = */ std::true_type) noexcept
{
    __unseq_backend::__simd_generate_n(__first, __last - __first, __g);
}

template <class _ForwardIterator, class _Generator>
void
__brick_generate(_ForwardIterator __first, _ForwardIterator __last, _Generator __g,
                 /* is_vector = */ std::false_type) noexcept
{
    std::generate(__first, __last, __g);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Generator, class _IsVector>
void
__pattern_generate(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Generator __g,
                   /*is_parallel=*/std::false_type, _IsVector __is_vector) noexcept
{
    __internal::__brick_generate(__first, __last, __g, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _Generator, class _IsVector>
_ForwardIterator
__pattern_generate(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Generator __g,
                   /*is_parallel=*/std::true_type, _IsVector __is_vector)
{
    return __internal::__except_handler([&]() {
        __par_backend::__parallel_for(std::forward<_ExecutionPolicy>(__exec), __first, __last,
                                      [__g, __is_vector](_ForwardIterator __begin, _ForwardIterator __end) {
                                          __internal::__brick_generate(__begin, __end, __g, __is_vector);
                                      });
        return __last;
    });
}

template <class OutputIterator, class Size, class _Generator>
OutputIterator
__brick_generate_n(OutputIterator __first, Size __count, _Generator __g, /* is_vector = */ std::true_type) noexcept
{
    return __unseq_backend::__simd_generate_n(__first, __count, __g);
}

template <class OutputIterator, class Size, class _Generator>
OutputIterator
__brick_generate_n(OutputIterator __first, Size __count, _Generator __g, /* is_vector = */ std::false_type) noexcept
{
    return std::generate_n(__first, __count, __g);
}

template <class _ExecutionPolicy, class _OutputIterator, class _Size, class _Generator, class _IsVector>
_OutputIterator
__pattern_generate_n(_ExecutionPolicy&&, _OutputIterator __first, _Size __count, _Generator __g,
                     /*is_parallel=*/std::false_type, _IsVector __is_vector) noexcept
{
    return __internal::__brick_generate_n(__first, __count, __g, __is_vector);
}

template <class _ExecutionPolicy, class _OutputIterator, class _Size, class _Generator, class _IsVector>
_OutputIterator
__pattern_generate_n(_ExecutionPolicy&& __exec, _OutputIterator __first, _Size __count, _Generator __g,
                     /*is_parallel=*/std::true_type, _IsVector __is_vector)
{
    static_assert(__is_random_access_iterator<_OutputIterator>::value,
                  "Pattern-brick error. Should be a random access iterator.");
    return __internal::__pattern_generate(std::forward<_ExecutionPolicy>(__exec), __first, __first + __count, __g,
                                          std::true_type(), __is_vector);
}

//------------------------------------------------------------------------
// remove
//------------------------------------------------------------------------

template <class _ForwardIterator, class _UnaryPredicate>
_ForwardIterator
__brick_remove_if(_ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
                  /* __is_vector = */ std::false_type) noexcept
{
    return std::remove_if(__first, __last, __pred);
}

template <class _RandomAccessIterator, class _UnaryPredicate>
_RandomAccessIterator
__brick_remove_if(_RandomAccessIterator __first, _RandomAccessIterator __last, _UnaryPredicate __pred,
                  /* __is_vector = */ std::true_type) noexcept
{
#if _PSTL_MONOTONIC_PRESENT
    return __unseq_backend::__simd_remove_if(__first, __last - __first, __pred);
#else
    return std::remove_if(__first, __last, __pred);
#endif
}

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
_ForwardIterator
__pattern_remove_if(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _UnaryPredicate __pred,
                    _IsVector __is_vector, /*is_parallel*/ std::false_type) noexcept
{
    return __internal::__brick_remove_if(__first, __last, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator, class _UnaryPredicate, class _IsVector>
_ForwardIterator
__pattern_remove_if(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last,
                    _UnaryPredicate __pred, _IsVector __is_vector, /*is_parallel*/ std::true_type) noexcept
{
    typedef typename std::iterator_traits<_ForwardIterator>::reference _ReferenceType;

    if (__first == __last || __first + 1 == __last)
    {
        // Trivial sequence - use serial algorithm
        return __internal::__brick_remove_if(__first, __last, __pred, __is_vector);
    }

    return __internal::__remove_elements(
        std::forward<_ExecutionPolicy>(__exec), __first, __last,
        [&__pred, __is_vector](bool* __b, bool* __e, _ForwardIterator __it) {
            __internal::__brick_walk2(__b, __e, __it, [&__pred](bool& __x, _ReferenceType __y) { __x = !__pred(__y); },
                                      __is_vector);
        },
        __is_vector);
}

//------------------------------------------------------------------------
// merge
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_merge(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
              _ForwardIterator2 __last2, _OutputIterator __d_first, _Compare __comp,
              /* __is_vector = */ std::false_type) noexcept
{
    return std::merge(__first1, __last1, __first2, __last2, __d_first, __comp);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_merge(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
              _ForwardIterator2 __last2, _OutputIterator __d_first, _Compare __comp,
              /* __is_vector = */ std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial");
    return std::merge(__first1, __last1, __first2, __last2, __d_first, __comp);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_merge(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                _ForwardIterator2 __last2, _OutputIterator __d_first, _Compare __comp, _IsVector __is_vector,
                /* is_parallel = */ std::false_type) noexcept
{
    return __internal::__brick_merge(__first1, __last1, __first2, __last2, __d_first, __comp, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_merge(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
                _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _OutputIterator __d_first,
                _Compare __comp, _IsVector __is_vector, /* is_parallel = */ std::true_type)
{
    __par_backend::__parallel_merge(
        std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __d_first, __comp,
        [__is_vector](_RandomAccessIterator1 __f1, _RandomAccessIterator1 __l1, _RandomAccessIterator2 __f2,
                      _RandomAccessIterator2 __l2, _OutputIterator __f3, _Compare __comp) {
            return __internal::__brick_merge(__f1, __l1, __f2, __l2, __f3, __comp, __is_vector);
        });
    return __d_first + (__last1 - __first1) + (__last2 - __first2);
}

//------------------------------------------------------------------------
// inplace_merge
//------------------------------------------------------------------------
template <class _BidirectionalIterator, class _Compare>
void
__brick_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
                      _Compare __comp, /* __is_vector = */ std::false_type) noexcept
{
    std::inplace_merge(__first, __middle, __last, __comp);
}

template <class _BidirectionalIterator, class _Compare>
void
__brick_inplace_merge(_BidirectionalIterator __first, _BidirectionalIterator __middle, _BidirectionalIterator __last,
                      _Compare __comp, /* __is_vector = */ std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial")
    std::inplace_merge(__first, __middle, __last, __comp);
}

template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare, class _IsVector>
void
__pattern_inplace_merge(_ExecutionPolicy&&, _BidirectionalIterator __first, _BidirectionalIterator __middle,
                        _BidirectionalIterator __last, _Compare __comp, _IsVector __is_vector,
                        /* is_parallel = */ std::false_type) noexcept
{
    __internal::__brick_inplace_merge(__first, __middle, __last, __comp, __is_vector);
}

template <class _ExecutionPolicy, class _BidirectionalIterator, class _Compare, class _IsVector>
void
__pattern_inplace_merge(_ExecutionPolicy&& __exec, _BidirectionalIterator __first, _BidirectionalIterator __middle,
                        _BidirectionalIterator __last, _Compare __comp, _IsVector __is_vector,
                        /*is_parallel=*/std::true_type)
{
    if (__first == __last || __first == __middle || __middle == __last)
    {
        return;
    }
    typedef typename std::iterator_traits<_BidirectionalIterator>::value_type _Tp;
    auto __n = __last - __first;
    __par_backend::__buffer<_Tp> __buf(__n);
    _Tp* __r = __buf.get();
    __internal::__except_handler([&]() {
        auto __move_values = [](_BidirectionalIterator __x, _Tp* __z) {
            __internal::__invoke_if_else(std::is_trivial<_Tp>(), [&]() { *__z = std::move(*__x); },
                                         [&]() { ::new (std::addressof(*__z)) _Tp(std::move(*__x)); });
        };

        auto __move_sequences = [](_BidirectionalIterator __first1, _BidirectionalIterator __last1, _Tp* __first2) {
            return __internal::__brick_uninitialized_move(__first1, __last1, __first2, _IsVector());
        };

        __par_backend::__parallel_merge(
            std::forward<_ExecutionPolicy>(__exec), __first, __middle, __middle, __last, __r, __comp,
            [__n, __move_values, __move_sequences](_BidirectionalIterator __f1, _BidirectionalIterator __l1,
                                                   _BidirectionalIterator __f2, _BidirectionalIterator __l2, _Tp* __f3,
                                                   _Compare __comp) {
                (__utils::__serial_move_merge(__n))(__f1, __l1, __f2, __l2, __f3, __comp, __move_values, __move_values,
                                                    __move_sequences, __move_sequences);
                return __f3 + (__l1 - __f1) + (__l2 - __f2);
            });
        __par_backend::__parallel_for(
            std::forward<_ExecutionPolicy>(__exec), __r, __r + __n, [__r, __first, __is_vector](_Tp* __i, _Tp* __j) {
                __brick_move_destroy()(__i, __j, __first + (__i - __r), __is_vector);
            });
    });
}

//------------------------------------------------------------------------
// includes
//------------------------------------------------------------------------

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_includes(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                   _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector,
                   /*is_parallel=*/std::false_type) noexcept
{
    return std::includes(__first1, __last1, __first2, __last2, __comp);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_includes(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                   _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp, _IsVector,
                   /*is_parallel=*/std::true_type)
{
    if (__first2 >= __last2)
        return true;

    if (__first1 >= __last1 || __comp(*__first2, *__first1) || __comp(*(__last1 - 1), *(__last2 - 1)))
        return false;

    __first1 = std::lower_bound(__first1, __last1, *__first2, __comp);
    if (__first1 == __last1)
        return false;

    if (__last2 - __first2 == 1)
        return !__comp(*__first1, *__first2) && !__comp(*__first2, *__first1);

    return __internal::__except_handler([&]() {
        return !__internal::__parallel_or(
            std::forward<_ExecutionPolicy>(__exec), __first2, __last2,
            [__first1, __last1, __first2, __last2, &__comp](_ForwardIterator2 __i, _ForwardIterator2 __j) {
                _PSTL_ASSERT(__j > __i);
                //assert(__j - __i > 1);

                //1. moving boundaries to "consume" subsequence of equal elements
                auto __is_equal = [&__comp](_ForwardIterator2 __a, _ForwardIterator2 __b) -> bool {
                    return !__comp(*__a, *__b) && !__comp(*__b, *__a);
                };

                //1.1 left bound, case "aaa[aaaxyz...]" - searching "x"
                if (__i > __first2 && __is_equal(__i, __i - 1))
                {
                    //whole subrange continues to content equal elements - return "no op"
                    if (__is_equal(__i, __j - 1))
                        return false;

                    __i = std::upper_bound(__i, __last2, *__i, __comp);
                }

                //1.2 right bound, case "[...aaa]aaaxyz" - searching "x"
                if (__j < __last2 && __is_equal(__j - 1, __j))
                    __j = std::upper_bound(__j, __last2, *__j, __comp);

                //2. testing is __a subsequence of the second range included into the first range
                auto __b = std::lower_bound(__first1, __last1, *__i, __comp);

                _PSTL_ASSERT(!__comp(*(__last1 - 1), *__b));
                _PSTL_ASSERT(!__comp(*(__j - 1), *__i));
                return !std::includes(__b, __last1, __i, __j, __comp);
            });
    });
}

constexpr auto __set_algo_cut_off = 1000;

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector, class _SizeFunction, class _SetOP>
_OutputIterator
__parallel_set_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                  _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                  _SizeFunction __size_func, _SetOP __set_op, _IsVector __is_vector)
{
    typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;
    typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;

    struct _SetRange
    {
        _DifferenceType __pos, __len, __buf_pos;
        bool
        empty() const
        {
            return __len == 0;
        }
    };

    const _DifferenceType __n1 = __last1 - __first1;
    const _DifferenceType __n2 = __last2 - __first2;

    __par_backend::__buffer<_Tp> __buf(__size_func(__n1, __n2));

    return __internal::__except_handler([&__exec, __n1, __first1, __last1, __first2, __last2, __result, __is_vector,
                                         __comp, __size_func, __set_op, &__buf]() {
        auto __buffer = __buf.get();
        _DifferenceType __m{};
        auto __scan = [=](_DifferenceType, _DifferenceType, const _SetRange& __s) { // Scan
            if (!__s.empty())
                __brick_move_destroy()(__buffer + __s.__buf_pos,
                                                         __buffer + (__s.__buf_pos + __s.__len), __result + __s.__pos,
                                                         __is_vector);
        };
        __par_backend::__parallel_strict_scan(
            std::forward<_ExecutionPolicy>(__exec), __n1, _SetRange{0, 0, 0}, //-1, 0},
            [=](_DifferenceType __i, _DifferenceType __len) {                 // Reduce
                //[__b; __e) - a subrange of the first sequence, to reduce
                _ForwardIterator1 __b = __first1 + __i, __e = __first1 + (__i + __len);

                //try searching for the first element which not equal to *__b
                if (__b != __first1)
                    __b = std::upper_bound(__b, __last1, *__b, __comp);

                //try searching for the first element which not equal to *__e
                if (__e != __last1)
                    __e = std::upper_bound(__e, __last1, *__e, __comp);

                //check is [__b; __e) empty
                if (__e - __b < 1)
                {
                    _ForwardIterator2 __bb = __last2;
                    if (__b != __last1)
                        __bb = std::lower_bound(__first2, __last2, *__b, __comp);

                    const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2));
                    return _SetRange{0, 0, __buf_pos};
                }

                //try searching for "corresponding" subrange [__bb; __ee) in the second sequence
                _ForwardIterator2 __bb = __first2;
                if (__b != __first1)
                    __bb = std::lower_bound(__first2, __last2, *__b, __comp);

                _ForwardIterator2 __ee = __last2;
                if (__e != __last1)
                    __ee = std::lower_bound(__bb, __last2, *__e, __comp);

                const _DifferenceType __buf_pos = __size_func((__b - __first1), (__bb - __first2));
                auto __buffer_b = __buffer + __buf_pos;
                auto __res = __set_op(__b, __e, __bb, __ee, __buffer_b, __comp);

                return _SetRange{0, __res - __buffer_b, __buf_pos};
            },
            [](const _SetRange& __a, const _SetRange& __b) { // Combine
                if (__b.__buf_pos > __a.__buf_pos || ((__b.__buf_pos == __a.__buf_pos) && !__b.empty()))
                    return _SetRange{__a.__pos + __a.__len + __b.__pos, __b.__len, __b.__buf_pos};
                return _SetRange{__b.__pos + __b.__len + __a.__pos, __a.__len, __a.__buf_pos};
            },
            __scan,                                     // Scan
            [&__m, &__scan](const _SetRange& __total) { // Apex
                //final scan
                __scan(0, 0, __total);
                __m = __total.__pos + __total.__len;
            });
        return __result + __m;
    });
}

//a shared parallel pattern for '__pattern_set_union' and '__pattern_set_symmetric_difference'
template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _SetUnionOp, class _IsVector>
_OutputIterator
__parallel_set_union_op(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                        _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
                        _Compare __comp, _SetUnionOp __set_union_op, _IsVector __is_vector)
{
    typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;

    const auto __n1 = __last1 - __first1;
    const auto __n2 = __last2 - __first2;

    auto __copy_range1 = [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) {
        return __internal::__brick_copy(__begin, __end, __res, __is_vector);
    };
    auto __copy_range2 = [__is_vector](_ForwardIterator2 __begin, _ForwardIterator2 __end, _OutputIterator __res) {
        return __internal::__brick_copy(__begin, __end, __res, __is_vector);
    };

    // {1} {}: parallel copying just first sequence
    if (__n2 == 0)
        return __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result,
                                                 __copy_range1, std::true_type());

    // {} {2}: parallel copying justmake  second sequence
    if (__n1 == 0)
        return __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result,
                                                 __copy_range2, std::true_type());

    // testing  whether the sequences are intersected
    _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);

    if (__left_bound_seq_1 == __last1)
    {
        //{1} < {2}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2
        __par_backend::__parallel_invoke(
            std::forward<_ExecutionPolicy>(__exec),
            [=] {
                __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result,
                                                  __copy_range1, std::true_type());
            },
            [=] {
                __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first2, __last2,
                                                  __result + __n1, __copy_range2, std::true_type());
            });
        return __result + __n1 + __n2;
    }

    // testing  whether the sequences are intersected
    _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);

    if (__left_bound_seq_2 == __last2)
    {
        //{2} < {1}: seq2 is wholly greater than seq1, so, do parallel copying seq1 and seq2
        __par_backend::__parallel_invoke(
            std::forward<_ExecutionPolicy>(__exec),
            [=] {
                __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first2, __last2, __result,
                                                  __copy_range2, std::true_type());
            },
            [=] {
                __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first1, __last1,
                                                  __result + __n2, __copy_range1, std::true_type());
            });
        return __result + __n1 + __n2;
    }

    const auto __m1 = __left_bound_seq_1 - __first1;
    if (__m1 > __set_algo_cut_off)
    {
        auto __res_or = __result;
        __result += __m1; //we know proper offset due to [first1; left_bound_seq_1) < [first2; last2)
        __par_backend::__parallel_invoke(
            std::forward<_ExecutionPolicy>(__exec),
            //do parallel copying of [first1; left_bound_seq_1)
            [=] {
                __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first1, __left_bound_seq_1,
                                                  __res_or, __copy_range1, std::true_type());
            },
            [=, &__result] {
                __result = __internal::__parallel_set_op(
                    std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result,
                    __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op,
                    __is_vector);
            });
        return __result;
    }

    const auto __m2 = __left_bound_seq_2 - __first2;
    _PSTL_ASSERT(__m1 == 0 || __m2 == 0);
    if (__m2 > __set_algo_cut_off)
    {
        auto __res_or = __result;
        __result += __m2; //we know proper offset due to [first2; left_bound_seq_2) < [first1; last1)
        __par_backend::__parallel_invoke(
            std::forward<_ExecutionPolicy>(__exec),
            //do parallel copying of [first2; left_bound_seq_2)
            [=] {
                __internal::__pattern_walk2_brick(std::forward<_ExecutionPolicy>(__exec), __first2, __left_bound_seq_2,
                                                  __res_or, __copy_range2, std::true_type());
            },
            [=, &__result] {
                __result = __internal::__parallel_set_op(
                    std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result,
                    __comp, [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op,
                    __is_vector);
            });
        return __result;
    }

    return __internal::__parallel_set_op(
        std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
        [](_DifferenceType __n, _DifferenceType __m) { return __n + __m; }, __set_union_op, __is_vector);
}

//------------------------------------------------------------------------
// set_union
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_union(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                  _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                  /*__is_vector=*/std::false_type) noexcept
{
    return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
}

template <typename _IsVector>
struct __BrickCopyConstruct
{
    template <typename _ForwardIterator, typename _OutputIterator>
    _OutputIterator
    operator()(_ForwardIterator __first, _ForwardIterator __last, _OutputIterator __result)
    {
        return __brick_uninitialized_copy(__first, __last, __result, _IsVector());
    }
};

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_union(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                  _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                  /*__is_vector=*/std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial");
    return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_union(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                    _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                    _IsVector __is_vector,
                    /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_set_union(__first1, __last1, __first2, __last2, __result, __comp, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_union(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                    _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                    _IsVector __is_vector, /*__is_parallel=*/std::true_type)
{

    const auto __n1 = __last1 - __first1;
    const auto __n2 = __last2 - __first2;

    // use serial algorithm
    if (__n1 + __n2 <= __set_algo_cut_off)
        return std::set_union(__first1, __last1, __first2, __last2, __result, __comp);

    typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
    return __parallel_set_union_op(
        std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
        [](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
           _Tp* __result, _Compare __comp) {
            return __pstl::__utils::__set_union_construct(__first1, __last1, __first2, __last2, __result, __comp,
                                                          __BrickCopyConstruct<_IsVector>());
        },
        __is_vector);
}

//------------------------------------------------------------------------
// set_intersection
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_intersection(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                         _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                         /*__is_vector=*/std::false_type) noexcept
{
    return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_intersection(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                         _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                         /*__is_vector=*/std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial");
    return std::set_intersection(__first1, __last1, __first2, __last2, __result, __comp);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_intersection(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                           _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
                           _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_set_intersection(__first1, __last1, __first2, __last2, __result, __comp, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_intersection(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                           _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
                           _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
    typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
    typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;

    const auto __n1 = __last1 - __first1;
    const auto __n2 = __last2 - __first2;

    // intersection is empty
    if (__n1 == 0 || __n2 == 0)
        return __result;

    // testing  whether the sequences are intersected
    _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);
    //{1} < {2}: seq 2 is wholly greater than seq 1, so, the intersection is empty
    if (__left_bound_seq_1 == __last1)
        return __result;

    // testing  whether the sequences are intersected
    _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);
    //{2} < {1}: seq 1 is wholly greater than seq 2, so, the intersection is empty
    if (__left_bound_seq_2 == __last2)
        return __result;

    const auto __m1 = __last1 - __left_bound_seq_1 + __n2;
    if (__m1 > __set_algo_cut_off)
    {
        //we know proper offset due to [first1; left_bound_seq_1) < [first2; last2)
        return __internal::__parallel_set_op(
            std::forward<_ExecutionPolicy>(__exec), __left_bound_seq_1, __last1, __first2, __last2, __result, __comp,
            [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
            [](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
               _ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
                return __pstl::__utils::__set_intersection_construct(__first1, __last1, __first2, __last2, __result,
                                                                     __comp);
            },
            __is_vector);
    }

    const auto __m2 = __last2 - __left_bound_seq_2 + __n1;
    if (__m2 > __set_algo_cut_off)
    {
        //we know proper offset due to [first2; left_bound_seq_2) < [first1; last1)
        __result = __internal::__parallel_set_op(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __left_bound_seq_2, __last2, __result, __comp,
            [](_DifferenceType __n, _DifferenceType __m) { return std::min(__n, __m); },
            [](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
               _ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
                return __pstl::__utils::__set_intersection_construct(__first2, __last2, __first1, __last1, __result,
                                                                     __comp);
            },
            __is_vector);
        return __result;
    }

    // [left_bound_seq_1; last1) and [left_bound_seq_2; last2) - use serial algorithm
    return std::set_intersection(__left_bound_seq_1, __last1, __left_bound_seq_2, __last2, __result, __comp);
}

//------------------------------------------------------------------------
// set_difference
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                       _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                       /*__is_vector=*/std::false_type) noexcept
{
    return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                       _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                       /*__is_vector=*/std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial");
    return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_difference(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
                         _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_set_difference(__first1, __last1, __first2, __last2, __result, __comp, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                         _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
                         _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{
    typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
    typedef typename std::iterator_traits<_ForwardIterator1>::difference_type _DifferenceType;

    const auto __n1 = __last1 - __first1;
    const auto __n2 = __last2 - __first2;

    // {} \ {2}: the difference is empty
    if (__n1 == 0)
        return __result;

    // {1} \ {}: parallel copying just first sequence
    if (__n2 == 0)
        return __internal::__pattern_walk2_brick(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result,
            [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) {
                return __internal::__brick_copy(__begin, __end, __res, __is_vector);
            },
            std::true_type());

    // testing  whether the sequences are intersected
    _ForwardIterator1 __left_bound_seq_1 = std::lower_bound(__first1, __last1, *__first2, __comp);
    //{1} < {2}: seq 2 is wholly greater than seq 1, so, parallel copying just first sequence
    if (__left_bound_seq_1 == __last1)
        return __internal::__pattern_walk2_brick(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result,
            [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) {
                return __internal::__brick_copy(__begin, __end, __res, __is_vector);
            },
            std::true_type());

    // testing  whether the sequences are intersected
    _ForwardIterator2 __left_bound_seq_2 = std::lower_bound(__first2, __last2, *__first1, __comp);
    //{2} < {1}: seq 1 is wholly greater than seq 2, so, parallel copying just first sequence
    if (__left_bound_seq_2 == __last2)
        return __internal::__pattern_walk2_brick(
            std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __result,
            [__is_vector](_ForwardIterator1 __begin, _ForwardIterator1 __end, _OutputIterator __res) {
                return __internal::__brick_copy(__begin, __end, __res, __is_vector);
            },
            std::true_type());

    if (__n1 + __n2 > __set_algo_cut_off)
        return __parallel_set_op(std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result,
                                 __comp, [](_DifferenceType __n, _DifferenceType) { return __n; },
                                 [](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                                    _ForwardIterator2 __last2, _Tp* __result, _Compare __comp) {
                                     return __pstl::__utils::__set_difference_construct(
                                         __first1, __last1, __first2, __last2, __result, __comp,
                                         __BrickCopyConstruct<_IsVector>());
                                 },
                                 __is_vector);

    // use serial algorithm
    return std::set_difference(__first1, __last1, __first2, __last2, __result, __comp);
}

//------------------------------------------------------------------------
// set_symmetric_difference
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_symmetric_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                                 _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                                 /*__is_vector=*/std::false_type) noexcept
{
    return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator, class _Compare>
_OutputIterator
__brick_set_symmetric_difference(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                                 _ForwardIterator2 __last2, _OutputIterator __result, _Compare __comp,
                                 /*__is_vector=*/std::true_type) noexcept
{
    _PSTL_PRAGMA_MESSAGE("Vectorized algorithm unimplemented, redirected to serial");
    return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_symmetric_difference(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                                   _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
                                   _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::false_type) noexcept
{
    return __internal::__brick_set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp,
                                                        __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _OutputIterator,
          class _Compare, class _IsVector>
_OutputIterator
__pattern_set_symmetric_difference(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                                   _ForwardIterator2 __first2, _ForwardIterator2 __last2, _OutputIterator __result,
                                   _Compare __comp, _IsVector __is_vector, /*is_parallel=*/std::true_type)
{

    const auto __n1 = __last1 - __first1;
    const auto __n2 = __last2 - __first2;

    // use serial algorithm
    if (__n1 + __n2 <= __set_algo_cut_off)
        return std::set_symmetric_difference(__first1, __last1, __first2, __last2, __result, __comp);

    typedef typename std::iterator_traits<_OutputIterator>::value_type _Tp;
    return __internal::__parallel_set_union_op(
        std::forward<_ExecutionPolicy>(__exec), __first1, __last1, __first2, __last2, __result, __comp,
        [](_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2, _ForwardIterator2 __last2,
           _Tp* __result, _Compare __comp) {
            return __pstl::__utils::__set_symmetric_difference_construct(__first1, __last1, __first2, __last2, __result,
                                                                         __comp, __BrickCopyConstruct<_IsVector>());
        },
        __is_vector);
}

//------------------------------------------------------------------------
// is_heap_until
//------------------------------------------------------------------------

template <class _RandomAccessIterator, class _Compare>
_RandomAccessIterator
__brick_is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
                      /* __is_vector = */ std::false_type) noexcept
{
    return std::is_heap_until(__first, __last, __comp);
}

template <class _RandomAccessIterator, class _Compare>
_RandomAccessIterator
__brick_is_heap_until(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp,
                      /* __is_vector = */ std::true_type) noexcept
{
    if (__last - __first < 2)
        return __last;
    typedef typename std::iterator_traits<_RandomAccessIterator>::difference_type _SizeType;
    return __unseq_backend::__simd_first(
        __first, _SizeType(0), __last - __first,
        [&__comp](_RandomAccessIterator __it, _SizeType __i) { return __comp(__it[(__i - 1) / 2], __it[__i]); });
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
_RandomAccessIterator
__pattern_is_heap_until(_ExecutionPolicy&&, _RandomAccessIterator __first, _RandomAccessIterator __last,
                        _Compare __comp, _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept
{
    return __internal::__brick_is_heap_until(__first, __last, __comp, __is_vector);
}

template <class _RandomAccessIterator, class _DifferenceType, class _Compare>
_RandomAccessIterator
__is_heap_until_local(_RandomAccessIterator __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp,
                      /* __is_vector = */ std::false_type) noexcept
{
    _DifferenceType __i = __begin;
    for (; __i < __end; ++__i)
    {
        if (__comp(__first[(__i - 1) / 2], __first[__i]))
        {
            break;
        }
    }
    return __first + __i;
}

template <class _RandomAccessIterator, class _DifferenceType, class _Compare>
_RandomAccessIterator
__is_heap_until_local(_RandomAccessIterator __first, _DifferenceType __begin, _DifferenceType __end, _Compare __comp,
                      /* __is_vector = */ std::true_type) noexcept
{
    return __unseq_backend::__simd_first(
        __first, __begin, __end,
        [&__comp](_RandomAccessIterator __it, _DifferenceType __i) { return __comp(__it[(__i - 1) / 2], __it[__i]); });
}

template <class _ExecutionPolicy, class _RandomAccessIterator, class _Compare, class _IsVector>
_RandomAccessIterator
__pattern_is_heap_until(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
                        _Compare __comp, _IsVector __is_vector, /* is_parallel = */ std::true_type) noexcept
{
    if (__last - __first < 2)
        return __last;

    return __internal::__except_handler([&]() {
        return __parallel_find(
            std::forward<_ExecutionPolicy>(__exec), __first, __last,
            [__first, __comp, __is_vector](_RandomAccessIterator __i, _RandomAccessIterator __j) {
                return __internal::__is_heap_until_local(__first, __i - __first, __j - __first, __comp, __is_vector);
            },
            std::less<typename std::iterator_traits<_RandomAccessIterator>::difference_type>(), /*is_first=*/true);
    });
}

//------------------------------------------------------------------------
// min_element
//------------------------------------------------------------------------

template <typename _ForwardIterator, typename _Compare>
_ForwardIterator
__brick_min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp,
                    /* __is_vector = */ std::false_type) noexcept
{
    return std::min_element(__first, __last, __comp);
}

template <typename _ForwardIterator, typename _Compare>
_ForwardIterator
__brick_min_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp,
                    /* __is_vector = */ std::true_type) noexcept
{
#if _PSTL_UDR_PRESENT
    return __unseq_backend::__simd_min_element(__first, __last - __first, __comp);
#else
    return std::min_element(__first, __last, __comp);
#endif
}

template <typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare, typename _IsVector>
_ForwardIterator
__pattern_min_element(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp,
                      _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept
{
    return __internal::__brick_min_element(__first, __last, __comp, __is_vector);
}

template <typename _ExecutionPolicy, typename _RandomAccessIterator, typename _Compare, typename _IsVector>
_RandomAccessIterator
__pattern_min_element(_ExecutionPolicy&& __exec, _RandomAccessIterator __first, _RandomAccessIterator __last,
                      _Compare __comp, _IsVector __is_vector, /* is_parallel = */ std::true_type)
{
    if (__first == __last)
        return __last;

    return __internal::__except_handler([&]() {
        return __par_backend::__parallel_reduce(
            std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, __first,
            [=](_RandomAccessIterator __begin, _RandomAccessIterator __end,
                _RandomAccessIterator __init) -> _RandomAccessIterator {
                const _RandomAccessIterator subresult =
                    __internal::__brick_min_element(__begin, __end, __comp, __is_vector);
                return __internal::__cmp_iterators_by_values(__init, subresult, __comp);
            },
            [=](_RandomAccessIterator __it1, _RandomAccessIterator __it2) -> _RandomAccessIterator {
                return __internal::__cmp_iterators_by_values(__it1, __it2, __comp);
            });
    });
}

//------------------------------------------------------------------------
// minmax_element
//------------------------------------------------------------------------

template <typename _ForwardIterator, typename _Compare>
std::pair<_ForwardIterator, _ForwardIterator>
__brick_minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp,
                       /* __is_vector = */ std::false_type) noexcept
{
    return std::minmax_element(__first, __last, __comp);
}

template <typename _ForwardIterator, typename _Compare>
std::pair<_ForwardIterator, _ForwardIterator>
__brick_minmax_element(_ForwardIterator __first, _ForwardIterator __last, _Compare __comp,
                       /* __is_vector = */ std::true_type) noexcept
{
#if _PSTL_UDR_PRESENT
    return __unseq_backend::__simd_minmax_element(__first, __last - __first, __comp);
#else
    return std::minmax_element(__first, __last, __comp);
#endif
}

template <typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare, typename _IsVector>
std::pair<_ForwardIterator, _ForwardIterator>
__pattern_minmax_element(_ExecutionPolicy&&, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp,
                         _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept
{
    return __internal::__brick_minmax_element(__first, __last, __comp, __is_vector);
}

template <typename _ExecutionPolicy, typename _ForwardIterator, typename _Compare, typename _IsVector>
std::pair<_ForwardIterator, _ForwardIterator>
__pattern_minmax_element(_ExecutionPolicy&& __exec, _ForwardIterator __first, _ForwardIterator __last, _Compare __comp,
                         _IsVector __is_vector, /* is_parallel = */ std::true_type)
{
    if (__first == __last)
        return std::make_pair(__first, __first);

    return __internal::__except_handler([&]() {
        typedef std::pair<_ForwardIterator, _ForwardIterator> _Result;

        return __par_backend::__parallel_reduce(
            std::forward<_ExecutionPolicy>(__exec), __first + 1, __last, std::make_pair(__first, __first),
            [=](_ForwardIterator __begin, _ForwardIterator __end, _Result __init) -> _Result {
                const _Result __subresult = __internal::__brick_minmax_element(__begin, __end, __comp, __is_vector);
                return std::make_pair(
                    __internal::__cmp_iterators_by_values(__subresult.first, __init.first, __comp),
                    __internal::__cmp_iterators_by_values(__init.second, __subresult.second, std::not_fn(__comp)));
            },
            [=](_Result __p1, _Result __p2) -> _Result {
                return std::make_pair(
                    __internal::__cmp_iterators_by_values(__p1.first, __p2.first, __comp),
                    __internal::__cmp_iterators_by_values(__p2.second, __p1.second, std::not_fn(__comp)));
            });
    });
}

//------------------------------------------------------------------------
// mismatch
//------------------------------------------------------------------------
template <class _ForwardIterator1, class _ForwardIterator2, class _BinaryPredicate>
std::pair<_ForwardIterator1, _ForwardIterator2>
__mismatch_serial(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                  _ForwardIterator2 __last2, _BinaryPredicate __pred)
{
#if _PSTL_CPP14_2RANGE_MISMATCH_EQUAL_PRESENT
    return std::mismatch(__first1, __last1, __first2, __last2, __pred);
#else
    for (; __first1 != __last1 && __first2 != __last2 && __pred(*__first1, *__first2); ++__first1, ++__first2)
    {
    }
    return std::make_pair(__first1, __first2);
#endif
}

template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
std::pair<_ForwardIterator1, _ForwardIterator2>
__brick_mismatch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                 _ForwardIterator2 __last2, _Predicate __pred, /* __is_vector = */ std::false_type) noexcept
{
    return __mismatch_serial(__first1, __last1, __first2, __last2, __pred);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _Predicate>
std::pair<_ForwardIterator1, _ForwardIterator2>
__brick_mismatch(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                 _ForwardIterator2 __last2, _Predicate __pred, /* __is_vector = */ std::true_type) noexcept
{
    auto __n = std::min(__last1 - __first1, __last2 - __first2);
    return __unseq_backend::__simd_first(__first1, __n, __first2, std::not_fn(__pred));
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Predicate, class _IsVector>
std::pair<_ForwardIterator1, _ForwardIterator2>
__pattern_mismatch(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                   _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Predicate __pred, _IsVector __is_vector,
                   /* is_parallel = */ std::false_type) noexcept
{
    return __internal::__brick_mismatch(__first1, __last1, __first2, __last2, __pred, __is_vector);
}

template <class _ExecutionPolicy, class _RandomAccessIterator1, class _RandomAccessIterator2, class _Predicate,
          class _IsVector>
std::pair<_RandomAccessIterator1, _RandomAccessIterator2>
__pattern_mismatch(_ExecutionPolicy&& __exec, _RandomAccessIterator1 __first1, _RandomAccessIterator1 __last1,
                   _RandomAccessIterator2 __first2, _RandomAccessIterator2 __last2, _Predicate __pred,
                   _IsVector __is_vector, /* is_parallel = */ std::true_type) noexcept
{
    return __internal::__except_handler([&]() {
        auto __n = std::min(__last1 - __first1, __last2 - __first2);
        auto __result = __internal::__parallel_find(
            std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n,
            [__first1, __first2, __pred, __is_vector](_RandomAccessIterator1 __i, _RandomAccessIterator1 __j) {
                return __internal::__brick_mismatch(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1),
                                                    __pred, __is_vector)
                    .first;
            },
            std::less<typename std::iterator_traits<_RandomAccessIterator1>::difference_type>(), /*is_first=*/true);
        return std::make_pair(__result, __first2 + (__result - __first1));
    });
}

//------------------------------------------------------------------------
// lexicographical_compare
//------------------------------------------------------------------------

template <class _ForwardIterator1, class _ForwardIterator2, class _Compare>
bool
__brick_lexicographical_compare(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                                _ForwardIterator2 __last2, _Compare __comp,
                                /* __is_vector = */ std::false_type) noexcept
{
    return std::lexicographical_compare(__first1, __last1, __first2, __last2, __comp);
}

template <class _ForwardIterator1, class _ForwardIterator2, class _Compare>
bool
__brick_lexicographical_compare(_ForwardIterator1 __first1, _ForwardIterator1 __last1, _ForwardIterator2 __first2,
                                _ForwardIterator2 __last2, _Compare __comp, /* __is_vector = */ std::true_type) noexcept
{
    if (__first2 == __last2)
    { // if second sequence is empty
        return false;
    }
    else if (__first1 == __last1)
    { // if first sequence is empty
        return true;
    }
    else
    {
        typedef typename std::iterator_traits<_ForwardIterator1>::reference ref_type1;
        typedef typename std::iterator_traits<_ForwardIterator2>::reference ref_type2;
        --__last1;
        --__last2;
        auto __n = std::min(__last1 - __first1, __last2 - __first2);
        std::pair<_ForwardIterator1, _ForwardIterator2> __result = __unseq_backend::__simd_first(
            __first1, __n, __first2, [__comp](const ref_type1 __x, const ref_type2 __y) mutable {
                return __comp(__x, __y) || __comp(__y, __x);
            });

        if (__result.first == __last1 && __result.second != __last2)
        { // if first sequence shorter than second
            return !__comp(*__result.second, *__result.first);
        }
        else
        { // if second sequence shorter than first or both have the same number of elements
            return __comp(*__result.first, *__result.second);
        }
    }
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_lexicographical_compare(_ExecutionPolicy&&, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                                  _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp,
                                  _IsVector __is_vector, /* is_parallel = */ std::false_type) noexcept
{
    return __internal::__brick_lexicographical_compare(__first1, __last1, __first2, __last2, __comp, __is_vector);
}

template <class _ExecutionPolicy, class _ForwardIterator1, class _ForwardIterator2, class _Compare, class _IsVector>
bool
__pattern_lexicographical_compare(_ExecutionPolicy&& __exec, _ForwardIterator1 __first1, _ForwardIterator1 __last1,
                                  _ForwardIterator2 __first2, _ForwardIterator2 __last2, _Compare __comp,
                                  _IsVector __is_vector, /* is_parallel = */ std::true_type) noexcept
{
    if (__first2 == __last2)
    { // if second sequence is empty
        return false;
    }
    else if (__first1 == __last1)
    { // if first sequence is empty
        return true;
    }
    else
    {
        typedef typename std::iterator_traits<_ForwardIterator1>::reference _RefType1;
        typedef typename std::iterator_traits<_ForwardIterator2>::reference _RefType2;
        --__last1;
        --__last2;
        auto __n = std::min(__last1 - __first1, __last2 - __first2);
        auto __result = __internal::__parallel_find(
            std::forward<_ExecutionPolicy>(__exec), __first1, __first1 + __n,
            [__first1, __first2, &__comp, __is_vector](_ForwardIterator1 __i, _ForwardIterator1 __j) {
                return __internal::__brick_mismatch(__i, __j, __first2 + (__i - __first1), __first2 + (__j - __first1),
                                                    [&__comp](const _RefType1 __x, const _RefType2 __y) {
                                                        return !__comp(__x, __y) && !__comp(__y, __x);
                                                    },
                                                    __is_vector)
                    .first;
            },
            std::less<typename std::iterator_traits<_ForwardIterator1>::difference_type>(), /*is_first=*/true);

        if (__result == __last1 && __first2 + (__result - __first1) != __last2)
        { // if first sequence shorter than second
            return !__comp(*(__first2 + (__result - __first1)), *__result);
        }
        else
        { // if second sequence shorter than first or both have the same number of elements
            return __comp(*__result, *(__first2 + (__result - __first1)));
        }
    }
}

} // namespace __internal
} // namespace __pstl

#endif /* _PSTL_ALGORITHM_IMPL_H */
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    	                                          ,                     <                     M                     a                     t                                          __UNIQUE_ID_alias196 __UNIQUE_ID_alias195 __UNIQUE_ID_alias194 __UNIQUE_ID_depends193 ____versions __UNIQUE_ID_retpoline192 __UNIQUE_ID_intree191 __UNIQUE_ID_name190 __UNIQUE_ID_vermagic189 _note_10 _note_9 ip101a_read_page ip101g_get_sset_count phy_module_init icplus_driver ip101g_get_stats ip101g_get_strings ip101g_write_page ip101g_read_page ip101a_g_has_page_register ip1001_config_init ip101a_g_config_intr_pin ip101a_g_handle_interrupt ip175c_read_status ip175c_config_aneg ip101a_g_probe ip101a_g_probe.cold ip101a_config_init ip175c_config_init full_reset_performed.35 phy_module_exit ip101a_match_phy_device ip101g_config_init ip101a_write_page __already_done.0 ip101a_g_config_intr ip101a_g_read_status ip101a_g_config_aneg CSWTCH.31 CSWTCH.32 ip101g_match_phy_device icplus_tbl __UNIQUE_ID___addressable_cleanup_module389 __UNIQUE_ID___addressable_init_module388 __UNIQUE_ID_license387 __UNIQUE_ID_author386 __UNIQUE_ID_description385 .LC7 phy_error device_property_present devm_kmalloc __this_module __mdiobus_read cleanup_module __fentry__ init_module phy_read_paged phy_restore_page genphy_soft_reset phy_drivers_unregister __mdiobus_write genphy_resume __phy_modify _dev_err phy_modify_paged __x86_return_thunk strscpy __const_udelay __genphy_config_aneg phy_select_page phy_drivers_register __warn_printk phy_write_paged netif_carrier_on phy_trigger_machine genphy_read_status __mod_mdio__icplus_tbl_device_table genphy_suspend            A             N             A             N   !          A   A          C   v          C             N             A                                  O                                 O             A             G            A            ?   !         A   ?         L   a         R   r         N            L            R            N            N            A            L            R   7         N   N         L            R            N            A            S            I            D            A   $         C   4         N   <         X   G         N   O         ;   a         A   {         N            Y            N            A            N            Q            N            A            =               !                <               !                <            N   $            8       ,         <   5            <            8       D         <   a         A   v         M            N            A            
            N            W            R            L            P   :         R   ]         R   ~         R            L            P            
            A            N            N            A            K   )         N   F         K   a         A   m         N   s         	   }            P                	            U            N            A            V            N            C            N            C            V   !         A   -         Y   :         N   G         S   d         ?            ?            D            A            Q   	                                                S   5         I   Q         I   ]         D   l         N   q         A            N            N             A             >                                          T                                  J                                           
          F                                                                                                            (                    0                    8                    @                   H                   P                   X             `      `                   h                   p             `      x                                                                       `                                                                             p                    
                                                            q                                                         6                                       3      $             F      (             z      ,                   0                   4                   8                   <                   @                   D                   H                   L             (      P             l      T                   X                   \                   `             9      d             k      h                   l                                                                                                                                       '                    -                    6                            $                    (                    ,                    0                    4                    8                    <                    @                    D                    H                    L                   P                    T             '      X             -      \             .      `             n      d             o      h             q      l             v      p                   t                   x                   |                                                                                                                                                  6                   ;                                                                                                                                                                                                                                                                                              3                   8                   F                   K                   W                   `                                                                                                                                                                       !                  T                  `                  f                         $                  (                  ,                  0                  4                  8                  <                  @                  D                  H                  L                  P                  T                  X                  \                   `                  d            (      h            -      l            R      p            W      t            `      x                  |                                                                                                                                                                               '                  (                  )                  6                  7                  9                  >                                                                                                                                                                                                                                                                                                f                  g                   i                  k                                                                                                                                                                            :                        ~                                   [                    H                              0            `                                  E                                      [                    H           p                            E                       `                                 [                    H                                                                                                       0                    8            `      H                   p         E           x                                              [                    H                                                                                                p                                            @                   H                   P                               @                      B           8         B           P         @            .symtab .strtab .shstrtab .note.gnu.build-id .note.Linux .rela.text .rela.init.text .rela.text.unlikely .rela.exit.text .rela__mcount_loc .rodata.str1.1 .rodata.str1.8 .rodata .modinfo .rela.return_sites .orc_unwind .rela.orc_unwind_ip __versions .rela__bug_table .rela.data .rela.exit.data .rela.init.data .data.once .rela.gnu.linkonce.this_module .bss .comment .note.GNU-stack .BTF .gnu_debuglink                                                                                      @       $                              .                     d       <                              ?                                                         :      @               09            '                    J                     =	                                    E      @               @D      `       '                    Z                     Z	                                    U      @               D      H       '                    n                     s	                                    i      @               D      0       '   	                 ~                     	                                    y      @               E      (      '                          2               <
                                         2               
      0                                                  (                                                         4      P                                                        p                                    @               @G            '                                               6                                                  *      $                                   @               I            '                                         `                                                                                                   @               V      0       '                                                                             	     @               V            '                                        !                                         @               Z             '                    )                    !                                    $     @               Z             '                    4                    !                                    D                    !                    @               ?     @               Z      0       '                     ^                    @%                                    c     0               @%      P                             l                     %                                     |                     %      D                                                  *                                                          *            (   ;                 	                      3                                                         [                                   0	*H
01
0	`He0	*H
1a0]080 10UDebian Secure Boot CA2(oe:B&C0	`He0
	*H
  E#M3ccLWx8c2jc}%	u>XXdܷйgbmZjS<yr=*30ݵEqB$/!pBGx?E
Hl}:z{3rkmhm'x[7yT	zu0xԂs.dL:w-Aʹm
Dpv!ZьZ[#h^FWم         ~Module signature appended~
 070701000A037D000081A4000000000000000000000001682F6DA700051423000000CA0000000200000000000000000000004000000000usr/lib/modules/6.1.0-37-amd64/kernel/drivers/net/phy/libphy.ko   ELF          >                             @     @ J I          GNU 6/ŎXۉe͆_~J        Linux                Linux   6.1.0-37-amd64      HH  HtH8  Ht    ̸         HH  HtH@  Ht                 HH   tEATL   UHSHL    HH  HHH      L    1[]A\        f    USHH  Ht`H   tOH   tEH   t;H   HH    HH  HH      H    []    fD      HH   tOAUL   ATIUHSHL    LHHHH  H      L    1[]A\A]                   t	T  t        ff.     @     HH5    H              H5    H  1ɿ              9tUSHfHH  Ht=HH  Ht1H[    E1v*1Ƀv-H    HH        [        L    ̉H    ǐ    HH   t                       AUATU1SHH  H    t8L   HAL    HH  HDH       L    []A\A]    ff.     f    HH  HtH  Ht      t        f.         HH  H   Ht      t	T  t1        @     ATUSHLH    tpH8  HtDHp         uyHt"   tH   t   1H             []A\    H   H    HI$       H    []A\    HH   yH0     1        fD      AUATUS  H     I    uR  I    H    LE      H    MMHH8  H[H    ]A\A]    H  H  H u&t   t  H    LEn  I    YI    J   H    LE2f.         SHH  H  H  Ht    x  H[    f         SLGPHMuLx  1Iٹ   H            HH    H  HtH        [            H5    H  1ɿ            H5    H  1ɿ            USHH   H    Hǃ         H5    1H      []            H  Ht0HH   t  t	T  t                D      H    HG    @uH@u;@u.@u!@ u@u    H/    H/H/H/H/H   D      UH   SHH      PwGH(  Ht    H    H5    H  1ǃ             H[]    1wH4    H        H[]    ff.           t1    SHH  HH   H  Ht    uD     t;t.H    H߾   ǃ     HX      H    1[    tHX  1Hǃ         H    1    |[            HH   twSH  t$H    x	  w[    H[  H  1ɋ      Ht  @  H   H  떸        UH   SHH    HOH    []    ff.         AUATUSH8eH%(   HD$0HH  He    H   H  AH$    HD$    HD$    HD$    HD$     HD$(    H      Ņt%HD$0eH+%(      H8[]A\A]          H    ~uuxu벺=      H    AŅ~<      H    ~H|$ 6AH|$(]   HT$Ht$ H           H    HvE&A   11Ҿ   H    
        ff.     @     HH   ]  U   HSH       '  Hfփ E־   ЀEЉ
   EЉ
    EЉ
   @EЉS<          fփ E։ЀEЉ
   EЉ
    EЃ@   1S   =   HC    xYfփ E։ЀEЉ
   EЉ
    EЉ
   @E1S#SC1[]          t    fD      AUATUHSHH  L8  H  H   r  H   d  L   HL               H    ŅtL    []A\A]    HX  1H    H    Im8   HH  HH      Ņ   HH  ǃ        u	x  uH5    H  1ɿ        cH        HtHE     @L    nH        HtHE     Iu8r)HX     H    H    H    L    H        HtHE              AVAUATUHSHH  L8  H  H   ~  H   p  L   HIL               H    ŅtL    []A\A]A^    HX  1H    H    Im8   HH  LHH      Ņ   HH  ǃ        u
x  yH5    H  1ɿ        ZH        HtHE     7L    gH        HtHE     Iu8r)HX     H    H    H    L    H        HtHE     f.         ATUSHH   )  I      H    Å   <      H       AT$1ɅtAL$u~P  !9tVɺ<      H    Åx0  t2H  t
T         1҅NЉӉ[]A\    1ۉ[]A\    É[]A\    ҉փ E։փE։փ   E։փ    E։փ@   E!.    tsfD      AWAVAUATUHSHHDfI     [G    H  uxFH  K      k      fC1H[]A\A]A^A_      u)H@  HtHGHtH[]A\A]A^A_    ̸H[]A\A]A^A_    Dv(  DE%   =   tzDnE1A9   H  ADD    D9(     EHH   H    HH߉D$    D$g(  fVAAE1AA9t*SDADH  	   @    oA  A	   E1Et_A=   /몉	ʁ   @    fC1}E!fEHH[]A\A]A^A_      fA    Aǃ  Df  A@S  ǅ    C% HH  fA    H(fA    H(CA   % H  A    H( A@   H(AĀ   H(fA    H(fA tH(
fA tYH(CA   % Aǃ  C% {H0CA   % bH0(H0CA   % ?H0
|H0eH0JH01H0 fA  tǅ  d   C% ǅ  
   C% @     H  Ht        HG8tH  Ht             USHeH%(   HD$1H$    HD$      u!1HT$eH+%(      H[]    H8  H]   H    H]tH  H  ]   HH$HGHD$H8  H  H@  HGHǃ8      Hǃ@          cH    X    ff.         AVAUATUSHDnDveH%(   HD$1DfF
;(  )  HF@HH]   H  HH$HFHHHD$    A      A  Adt
A
   A   L   L      H$AH H  HT$I	L  H   H  E    EQ  w7HL    1HT$eH+%(      H[]A\A]A^    H5    H  1ɿ    ǃ         뫸뮾]   H    H]tL   L      H$H  HT$H   H  1    ff.          H  Ht        ATL   UHSHL    H  HE0H  HE8H  HE@H   HEHH(  HEPH0  HEX  E  E  E  E  E     t  E	  LE(  E
  EQ  EP  E
[]A\    ff.          H  Ht    1        f         ATUSHeH%(   HD$1  u#1HT$eH+%(      H[]A\    H  HL  H$H   HD$    uH$]   HLH8  HD$H@      uH    x@md       uAtId       HH  HHtH  Hu  t        뻺    O    f.         HHH  H            USHHǨ  H       H      v
ǃ     H[]    ff.          HH    H  Ht    1    @     AVAULXATLgXUSHHL   LeH%(   HD$1D$     <   C  R     L    L    L[LA    AtkEy2L    Lǃ<       1Hڿ    H5        L	L    <t|{u	   L    HD$eH+%(   1  H[]A\A]A^    u.HHt$LH         |$    L    gH   u
{yH5       Hڿ        [LjLA    5 uML    L    L    L        Iv8rEǃ<   L    gL15H       L    L    L        D      AUATUS  L8  P   H   HH    D  AtnH(  Ht    ǃ     DHL   H    L    L    H      v
ǃ     [H]A\A]    H    H        Iu8mL    `H4    H        []A\A]    f.     f    1    @     S4     HƇ  Ƈ      x#% @  ҃    1[    ff.     f      '  t1    S      H    xtP  1[    ƃP  1f    U     SHƇ  Ƈ      Ņx3     H    x2   t      1[]        []        S      H    xtHA   11Ҿ   [    [    ff.     f    Dƹ @  1Ҿ   A    f      <t(v.<t"    E1 @  4         A @  1    f         AUATUHSX     A      ,   tK   DH    xpEtNtJHDHHAA!ă  tMx  t   DH    x%t   Eu  	Ј  1[]A\A]    HH     tS1Ҿ       x-1ff.          S      H    xtHE1   1Ҿ   [    [    ff.     f    SE1H   @tUH  H/s?1A               t[    1A   @   H߾       uA   1Hߺ      [    f    HT  t %   E1      H          H<$    1H<$x͉T          HT  t %   A   1ɾ   H          H<$    1H<$x͉T          HT  t*  t;       IH          H<$    H<$y   뾉T           UST  Ht\	@u   H    xt	1[]    T  t>%   HA   [1ɾ   ]              1҅xT  뇺      H    1҅xT      S1Ҿ   HHǇ(      HǇ0          xN%|   =@      B  @td   =    uLT    ǃ        u51[    	  =X   t=\     E봃҃ƃ  4     Hƃ      x% @  ҃    1넺      H    hT  X'  /         AU]   ATUSHH  HH      H    ŋT    
  L       HH  AAD@H  DEDH  DEDH  DED H  DED@   DE    &  L       HEH     I/AH0ADDEH  D    DE       t   []A\A]      <    L  H  H߾   D     D     I
AA
D@     DEº  fD     E    ŅzL   A̺  H߾   IAAE	E    y4[]A\A]          H     T  @@D      UST  H          H       H(       Hu       H        :  Hm  @!  Hm   Hm   Hm   Hm 
  Hm    H
     !       x5/      HU 0   @  HU   Hm 1[]         H    xH(      Hm      H    xV  Hu 
s  Hm    H
           f@\   6  HE 1L          (T  Hm IHu Hu 
Hu \   HE Hǃ      1Hu /   HE 0   HE Hu Hu  Hu Hu Hu Hu 
Hu Hǃ      1Hu 
Hu Hu Hu  Hu Hu 
Hm 
Hu 1AHU HU Hu HE 1        USH    Ņu3H   HHǃ      H    t    Ņt[]    []T  t$tH    ŅxH    []          H    xىT  ff.         UH  SHHu X  t          xOx        H    x1+   u/HU ,   @t/HU .    t/HU u/1[]    HU ,   @uHU .    uHU tѺ      H    x-      HU 7  Hm   Hm   Hm     Hm @   Hm    Hm Hm    Hm Hm  @   (      H    \      HE      H       Hm 1Hm }HU Hu Hu  mHu Hu GHu (Hu Hu Hu Hu       H    G/   t,HU 0   t
HU HU HE HU Hu 1ff.         ATUS    1Ҿ   H    Å         H       Aċ  =	       d   =     @A1Ҿ   H    ÅxyA̺      H    Åx]T     %   t"H    Åx9T     %   1҅	[HE1]      A\    É[]A\    
   T  tbtTA=B=  t&='     @   A	! A\   A1X   A0A      H    xቅT  뀺      H    T        H    1҅T       SH  t    x@H[@4[[              N  O  1	  5  ~uH    '  tD6  uAH                H    @
 t uTH          H    H    HE    H    dt~]  H    H    HE     H    H    HE    H    @  tP  u6H        H    c
H    H    HE    a  H    H    HE    H        H        H        @     H    w
H             w7      Ht         @u u	=     t1H            1f    HH  Hh  Ht    ̀=     t
    H                     AAE1E1H    IEu	Mt\9rFHH=    t:p@\wH2s09upIA9t.EuMLDHH=    uMutL    9rMMtML    fD      H    PHHH=    t;8r    D      SHH  H[        ATUSHeH%(   HD$1H$    HD$        t`  HtTH  H(  ]   H    1
HHPt+    H$sH,    t  9    HD$eH+%(   u
H[]A\        f.              AVAUATUS    HH  DHtHX  Ht[D]A\A]A^    L  D(    u]˺
   DL    @   DL    ˺
   DL    D   DL    1[]A\A]A^    DDL[	]A\   @A]A^    ɸ    D      SH  HHp      HH  H`  Ht
H[    ̀=     t[    H            ff.         ATAUHS    ÅxD9tDHVH؉[]A\    fD      AUAATAUSH  HHp      DDH    H  Hp      []A\A]    @     ATUHSxADЅAIH  Hp      []A\    ff.         AUAATAUSH  HHp      ED⋳(  H      H  Hp      []A\A]    f         (  AH  E    1҅O    ff.     @     AUAATAUHSH  Hp      ED⋵(  H      H  Hp      1N[]A\A]    @     H    t$H    t   H    H    HE            H(  H
  H(  H       ff.            t    ff.         SH  H]   H(  HeH%(   HD$1HH$    HD$        1
HHPtm    H$sH        HH H	H  tHD$eH+%(   u/H[    HD$eH+%(   uHH[      ff.     @          AUATUS    HH  AHtHP  Ht[]A\A]    H  D(    uR˺
   DH    @D   DH    
   DH       [DH]A\A]    D	   @[]A\A]        @     AVAAUAATIUDS    x+!	9t(DDL       I[]A\A]A^    [1]A\A]A^    D      ATAUSH  HHp      DH    H  Hp      []A\    ff.     @     AUAATAUHS    Åx4A9uO(  H  D    HADЅAIH  Hp      []A\A]    DHyf.         AVAAUAATIUS    Åx7A9uUA$(  I$  D    LaÉЅII$  Hp      []A\A]A^    DL(y    AWEAVAAUAATAUHS    Åx<A9u[(  AEDH      HADЅAIH  Hp      []A\A]A^A_    DHy@     AWEAVAAUAATAUHS    Åx<A9u`(  AEDH      HA(DЅAIH  Hp      1N[]A\A]A^A_    DHyff.     @     AVAAUAATIUDS    x'!	9tDDL    x1[]A\A]A^             AWIAVEAUAATAUSH  Hp      DDL    Åx/E!D	9tADDL    Å   II  Hp      []A\A]A^A_    1D      AWAVIAUEATAUSH  Hp      DL    Aǅx,E!D	9tDL    AǅxE1I  Hp      D[]A\A]A^A_    ff.         IHt\11    \w*H
s$D    H    HtE9D	tE	HHOAH9HAuH    1H    ff.     f        fD          fD      SH  H(  ]   HHeH%(   HD$1HH$    HD$        O   HrP    H$s<    uH<    t)H1HT$eH+%(   u
H[             H8  HtH  Ƈ       ff.         H8  HtHǀ      Ƈ                 HH  Ht(H   HtSH    u	  1[    1                            fD      ATUHH    SH    H    H    thHuPHuHu LcL    tH    L    u,SPP  1#CTtuHCXH    x.  HH    uH        1H[]A\    H    D$    D$H[]A\        AWAVAAUAATIH    US    H-    L} H    u/IH}L    ÅuEPD1Dt1ILI    uѻH        []A\A]A^A_    H    tHU HEHBHH     HHE H"HE    f.         H    ff.         ff.         SHH      H[    f    HHH          H    ff.         HHH          H    D      HHH      u  H    vH        H    H    H        H    D      HHH    P      H    ff.         HH1H    H8       H    D      UASAAHA   HPPPPPPPPP	P
PPP
AAPPPPPPPPPPPPPPH    P    H   y	    1H[]         UHH    SHeH%(   HD$1HT$$    D$    HD$        ÅtHD$eH+%(   uDH[]    H|$HL$HH        u$T$	ЉE 볻    f.         U	   SH(  Ƈ  Ƈ  H      x\u^1@Ń(  H  
       x0   Āu      t	@@  1  []    1@Ńff.         (  H          I    D      SH(  1H         ui     x  u	   u(  H         xYu(  H         x:11	  	Љ  Pt1[    ߈  1HH     SW        SH(  1H      x+@u-    ҃⦃d    1[              UHS    Åt	[]    1H    HpÅ    H    Å    []    ff.         S1H    HH  HtzH   HtH    uZ  HxAHH  H   HtH    x"HH  H  HtH    1҅O[    y[    1[    f    SHH@      H    H߾       H[    ff.     f    UHS1 tH    Ht[]    @     HHtH    1H        1            Hx  H    eH%(   HD$1H$    t#H    tH       H    HH          HT$eH+%(   u	H        ff.         AUATE1USHH  Ht6I    HAH= w H(  HLH    HA    [D]A\A]    ff.     @     USH8  HH@t;    HH`      H@  HtHGHtH[]    []        D      AUATUSH  Ht,L  HH}M(	  L    uHǃ      []A\A]    HcE LIǄH	          H}    H            ATUSH L8  HH  eH%(   HD$1D$   HD$    HD$       t1HT$eH+%(   u_H []A\    Ht$H    D$u6MtA$  u&HtH   HtH    u   떸    ff.              SHx  GwFH8  H   H`   tFH    HShH8  Ht|H    trHu2         H8  Hu]HShHtEH    t;  u2Hp  Ht   t
H   u  t,HH   t"1[    1    HChHtH    t   uӃ@H߈  [ff.     @     P  1u    E1ɺ<          1҅H    f               1    f.            11    ff.     f    1ɺ   1    ff.     f        1    ff.     @     USHH@       =    =	    1Ƀd
H߀  D1@        H e               (  H         xi       H9;           1ɺ @  1    H    1H[]    (  H         u+xH    H߉D$H        D$명yع@   ff.     @     AUATUSHH      L   HAL    Eu`  t=HH  AHH  HtH    Ņu  D	Ј  L    []A\A]      t    붽ff.     f    USH    HH   tH        H{( up      HHHC    HC8    HCH    HsC$       Ņ    f[]    H   H    H        []    HH        []        SHHǨ      H(  ǃ          HH  Hǃ(      HtH(  HtH    H߾       1HǃH      [    f.             fD      AWAVAUATUS~oIAII1I  A9tPLL    ÅtDmt9IcHi  ILAI      Au[]A\A]A^A_    1ۉ[]A\A]A^A_    ff.         ~-UHcHi  SHHHH      H9u[]        D         ySH0  Ht      t?H`  H  	HH9tt3   #   u       1       3P  #       f.         HtIHH  Ht=1   u    H   H<$    H<$1       H    fD      SH@u,(  H  1    x%   =   u1[    H߹      1[          t      H(  HH  HH    ff.         U1H    SH    HH    t
H[]    H    uH v1H    H    HH= vH1[H    ]    ff.         Etu2  
    u  
        fD          fD          HǇ      =  t,=	  t%1Ƀd
Ȁ  D1    @   f.         AT   USHH  <1        Ņ         L F#       P  0      (  H  1    Ł   xBtB    I9|   P  0      뺋(  H  1    Ł   u&x+         t:H[]A\    xH    H߉D$H        l$HH[]A\mff.     f    AWAVA
  AUAպ`   ATIUHH=    S    H   @   HLxH    HH    H@tHH@    HL    DsPH    DkTLcX    H-    H    HH    tH    H    HkH] H        1[]A\A]A^A_            HщH             Hf     HcHHcHHH9u    @     U1SHH   tH    H{h    H@    []             U1SHH   tH    H{h    H@    []             AWAVAUATUSHL     M(	  IIL    HcIH	  HtfMtL9ktL    +H{   Ct.P	xqL    I$  1H[]A\A]A^A_           H=        
  H$    HHtZMH$u+C   IH	  돾       냾
  L    H$HHCtLkkH    $f.         AVI    IιAUIH    ATI   Uպ  S    HtJLLH    ŅtH    []A\A]A^    L#HL    []A\A]A^        AWA
  AVIAUMATAԺp  USHH=        H  HI  HC@H   H    HC`    f%HCX    	L  Hǃ      D(  ǃ,     Hǃ      Hǃ       Hǃ     Hǃ      ǃT  f  DP  Mt@IE H\  HT  LHH)HT  I   H)΁   H  HIcDIVHA  H    x      H    H   ǃ      H    H        E11ɺ    H  H    H   Hǃ      H  H  H  H      MtV@tQImIň   	HL9t%u tHtH߉D$    Hc\$HH[]A\A]A^A_    DHitHf.         ATUSH8  H   H   H  H    HtH8  Hǀ      Hǃ8      Hǃ0      H    HChHt	Hx    HH   t)H    LchH    I       H    H߾       HL      HtHp  H@hHhI<$H9t	[]A\    []A\    HtH0  H        H    H    H8  H1H    H    HH   ZH    LchH    I    14fD      S  Hw*x  vH    Hǃ`      H[D    ff.     f    SHH@      H    H߾       H[    ff.     f    HHt0H    H    1    HHt,  t        1    ff.             H롐    ATL   USHL    HH  Ht!H   HtH    Ņu	  1L    []A\         AWAVAUE1ATIUSHHL  $L$HtHp  H@hLhI>L9t
        L    ID$hHz  Hx        E1I$8       IǄ$X      H  I$8  L  A$       I$(  H  I$8  A$  H  L0  H    LL    u#H    LL        A$  I$8   E  AǄ$     $A	$  D$A$  A$  EtAǄ$     Ht
I$8      L    ŅuEL    L    H[]A\A]A^A_    H   t	A$  I$8  L    A$     ID$h    H=            ID$hLH@8    ŅxLA       Ņ?ID$hHx    ID$h    L    I>L9;    1A$  1H    L        ID$h    H=        X    @     HtVUHSHH      ux  H`  VwH[]    H߉D$    D$H[]        fD      AUATUSHHtTHIAH    HH    1    HH      HDH    H߉    HcŅHEH[]A\A]            AVAH    AUIATIH1UHH    S    H    HHtz  HDH    ŅuEx  L`  Hr    H[]A\A]A^        H    H[]A\A]A^    HHc    H[]A\A]A^    HH         H  H
uVuH  Hu	F9F    fD      H@tH/H tH/
    H7H uH7
    D      H  H  ff.         H  H6H  fD      AUATUSHH  Ht)L  H}M(	  L    uHǃ      []A\A]    HcE LIǄH	          H}    H            UHAWAVAUI    ATISHHXHT$8H    HL$@LD$HLL$Px  eH%(   HD$ 1HH   H    HD$    LEt'H    tH       H|$    HT$H          IM        f    14@         USHH  @ti࿈       H    xkH   H    HH  HtH   HtH    u~  H    x  r)H8   tH`   tH    1H[]            tx        x  H    HD$    D$xx1    ff.         USH     @   @   1    Ņt	[]    H  H  ]   H    H     HH  H) H  EȉȀ@  E    ŅxtH߹   [   1]    [] (  H  1    x%   =   uE>    ATUSP  HtE1ɺ<             O  tO  <  $  <  <          	   H    Aą     E     H  H  ]   H    H     HH  ȃ@H  EȉH  EȉȀH  EȉȀ H  EȉȀ@  E    Aąxd(  H         xFuP@E   H[]A\   <   H[]A\YAD[]A\    H  	   HH  HȀ    E    xqH߾   []A\1mAff.          ATUS  H@    AąuR  uSP(  ǃ     Hǃ      H  <Pt\1         D[]A\    @t uǃ     PHǃ      <Puϋ(  H         x>H(  @u:H2)    tAH
t2H*
t!H*H    vAnH*H2H2
H
ff.         UHSH  H+H+H+	(  H         x8u;H3@t;H+ t;H+t;H+t;H+ u;1[]    H+@uH3 uH3uH3uH3 tŋ(  H         x t!H+t)H+Ā)   tH1H3H1tH3f.         S  H   @V  (  H    u|       xhH(      H3 @   H+   H+   H+   H+
   H+@   H+1[    
       xĀ   H(    H*   H*(  H  8HǇ(      1HǇ0      H+ @;H3;H3;H3;H3
;H3@;H316H(  H3H3H3 H3H3H3H3
H3H31(  H  	           [    H2(  H  IH2f         ATUSD  HA    AŅup  tEuxH   ƃ   H  Hǃ      ƃ     tH    x,H    x   PPt>t[]A\    []A\     tH    1[NЉՉ]A\    H    D      UH  SHHeH%(   HD$1H  H$H   HHD$@    ]   HH    u	  uHD$eH+%(   uH[]    H        ff.         UH  SHHHeH%(   HD$H  H$H  HHD$H$H  HD$H   HD$eH+%(   uH[]        @     UHcSHHeH%(   HD$1H  H0H  H  HHH$H@HD$nH$H  HD$H   HD$eH+%(   uH[]                H  H0
t@uH  H  H@H       H(
ې    ATUSHHLgheH%(   HD$1LH  I$   ,  I$      A$   t  1H    HH  H   HtH    Ņ  H    I$   H   HH  H  H@HEH  @u  H  t  H   t  HL      HE LHH$HEHD$H$HH  HD$H       H   uH  @   ǃ     1Ix  ǃx  I$   HHtT    Ņt,   H    HD$eH+%(   uGH[]A\    H  Hm 
Hm m  t	            D      AWAVAUA   ATAUHS1HH$EAEA  DDH  @       DDH  @A    Å   D	AA    t%=tA   A   DDtYEAFA   DDH  @    xXH$DD  @HBD    x4H$B	DII uH$XH1[]A\A]A^A_    H[]A\A]A^A_    %=:  @DH    Åx  @DH    x	É%=DDH  @    w%   =   2DDH  @    A%   =   2p@     AUATAUHSH   eH%(   H$   1H$    HD$HD$HD$HD$ HD$(HD$0HD$8HD$@HD$HHD$PHD$XHD$`HD$hHD$pHD$xHǄ$   tLH   1IDH    H$   eH+%(      HĐ   []A\A]           AŅxo   DH    xxAA	DD%=tiEu 	  tHDHz^I   1DH    Wt"tHAH:tuH$        (  HT  H  f    tH/
@8tH/    H7
@8uH7    ff.     @     AUIHATI̹]   UHHSHHeH%(   HD$1HH$    HD$        H$H
t(AE A$HD$eH+%(   u@H[]A\A]    H$HuAE  HE H
AE Ae HH
    fD      AWAVAUATUSHH    D|$@Ht=IEED$LH{HAWET$EL.    H; XuH1[]A\A]A^A_    f.         w"HcH  Ht1,  HD    1    ff.     f    HcH               1    @     SGH`tu	H[    HpH        H[    ff.     @     IHV HcRx(HHHHH    L    H    HHt1HH HH9uf    HHN HH    Hc(  IHHT
pH  H    H    UHAWAAVAAUEATSHH0HuLgxDMeL%    eH%(   HE1HE    E    H   H   HUHuȿT       IH   LMHEIz=   HuLUI   I   HIǁ      Iǁ       LM    LUEHA   T   fABHLEzEErFEjLj ATULM    XZHEeH+%(   u"He[A\A]A^A_]    I$H-        UHSHH       uFEH}E HH    DMLDEFH    H    PHEHU    H  X[]    []    f.     D$EEHD$    D      H  Hc(  H9Ј  u2SHH8      H  Hc(  HǄЈ      1[                H1H    H        H`HHE        UHSHv(    H= w]HH  Hu        HHǃ      HE0HCp    uH[]    H߉D$    D$H[]    H[]    D      S  Htuǃ     H  [    [    HwH        fD      SH 	  tUw,1    HH wH    uCHH[    u91҉t$H<$    H<$t$H= Hv       HH    HHH[    ff.         H        H                ,  8uH  Ht    1             AVAAUATUHSHcHGX    AfHLlpe    IE Ex%IEe
       [D]A\A]A^    IE IEe    H    sHcHLlpe    ExH    HtHxATEE   H    Xe
    t%e    IE g    [D]A\A]A^        ff.         AULp  ATAUSHL    DH    L    []A\A]    f.              AUIATL  UH  SǇ     H] Ht/H0  Ht    H   H    H  H    HL9uI	  Ht
       [I  ]A\A]        ff.     fAWIAAVAι   AUEATEUSHH@eH%(   HD$81Hl$HHIBH  ukP   LH    Ht3HxHs=   H$    H$HDyEDqFDiLfDaH    HD$8eH+%(   u2H@[]A\A]A^A_    uLL$    L$x    fD      H  Hc(  HЈ      SH,  uHЈ  1[       H        H0  HH= w_HtH        11A   A   H    H    H= w;H8     H    H  Hc(  nt[        t[        H   H`
  
      H   H`
  ǀ     HPPHǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ  Hǀ 	  Hǀ	      
  H
      Htǀ     (1    @     AULp  ATAUSHL    DH    L    []A\A]    f.         AVAUATUSH    H H    HX     H`     H  HHtH  HtHP  Lur  H  H] L  LHǅP      H    LH  HǅX          Lǅ         AŅ    Hp  H    H        H(	  H    H           H    L    HH=   Ht5Hc	  H	  H
.      1H    	  -  HEhHtH    Aƅuw1      HrH    H= vHtЃALct5J  HtH   H    H  H    IAuH	  Ht
       LE    [D]A\A]A^    H    H    ǅ     f[D]A\A]A^    LH    H        D[]A\A]A^    H N  w%H4?       Hc
2    H  HS㥛 HHH    H N  wMH4?       }LH        xLLH        LA    H  HS㥛 HHH    ff.     f    AWDAVDAAUATUHSHcHG`    AfHLlpe    IE Ex'IEe
       [D]A\A]A^A_    IE IEe    H    sHcHLlpe    ExH    HtHxATEE1H    Xe
    t'e    IE i    [D]A\A]A^A_             AVAAUAATIUDS    x+!	9t(DDL       I[]A\A]A^    [1]A\A]A^    D      AVLp  AUAATAUHLS    DDH    L    []A\A]A^    ff.     @     AVLp  AUAATAUHLS    DDH    L    []A\A]A^    ff.     @     AWLp  AVAAUAATEUHLSH    DDH    x-E!D	9t>DDH       ILD$    D$H[]A\A]A^A_    1f.         AWEAVLp  AUAATAUHLSH    DDH    x)E!D	9tDDH    x1LD$    D$H[]A\A]A^A_    f    HGhH   Ht                fD      SHH      H[    f    SH    H[    f         USHH0  Ht`    H8  HtIu    D  u[]        @  tǃ
v1H N  w/[H4?   ]    tH8  Htt[]    H  []HS㥛 HHH    f.         SHGhHH   Ht    H߾       1[    ff.     f    U1SHHHoh    H   HtH    u
H1[]    H߾   D$    D$H[]    f    USHfHC    HHC8    HCH    HCP        Ņ    []    HH    H    H        f.             fD      UHSfH    Åt4[]    HH    H    H        H    ÅuH    Å    []            ATH  A
  UHH=    S    HtoHHUDHǀ      H  HHC`    H    HC@Hǃ      Hǃ       H  D(      H    H[]A\    Hff.             1xH6H                  Fd7  =  t
  1    A 0        D^1DE@f#    E   E11Ƀ   )t~A      E        .Ƀ
  D    %         fD#    A    D    DV,    fD#    f#    EtfA v?fA 9A    E111E1ɸ `               tW1dt  u    
            UHS`  t(1HcÃHHHX  H<    ;`  rHX      Hp  HǅX      Ht    Hp      Hǅp      []    ff.          UHS   t}  tl`     HX  HHHHè   H9   ;   uHtyHh  H9t HtU1       H    Hh  []    Hh  Ht1    Hp  1    Hǅh      []    Hp         H8  H        Hh  H    D      AV   2   AUATUSHH   eH%(   H$   1ILLHH    `  u1E1H$   eH+%(     H   D[]A\A]A^    H=       
      Hp  HH  L`XD(  ǀ       I    H  LL   H    HH    Le H    Aą  `  
  HH<H    HX  H7  `    1H;`     A|     HT L   HL HX  IAD L$H    A$   H  Mt$XD(  LHH    M4$L    AątUt>HcHH,H)HHL,IHX  H    HH   I9uHX      Hp      Hp      Hǃp      ǃ`      Hǃh      H        AAH8  [H    ]A\A]    x  H    H    ǃx      H    H    H    ǃx      H    L        H    H        H            H    H߽            I    LH    HH          H    HD$    D$    H    H    H       H        H    H    H    H        H   H            H        H        H    L        H0  H            I$H    L        H    L        H    L        LH    H        LH    H        I   1LHKPH   H    HML    HELLHD$HD$($   HD$    L    HD$ eH+%(   u@HX[A\A]A^A_]    HKPHtMLH    H    HsH    H    HA        tH    H        H    H    LH        A    H3H            (  H        H        H            1    Hp  1    1Hh      H        H            1        SH            Å#  H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H       H        H    H        Åu%H    H        ÅtH            1    [        SH    H        ÅuH        ÅtH        [                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      (⨇"hztBP)xb]xQrDC.dNeۀx)՚!5X$*cd&-A|_+\(a홍Br:LѤ,
)n)@uJݡG\$=e>zaK;nʵաE=cTiXVƐ61c#.R1Vv
S8mly
'$
7Hrg7|#ʟGL'ŒB2[~S`G![Ha 1E6׫O#9HMvOL
w$n 	&_fY9 ;\'-¥W8Ets30-imlΥ")S6S,0@<qXe=Ԛ
?ӵIG.~S/J9Qn")Z/&@:JcN:CN\6˩D-3>8׍dTo+	|~zfU 6{ņtϱA "ژ
@Z`G^<+,vq7Td1
*
ۖx*uKOh 'O3еÝ]ePh
FW
Osp~Cc4x"z^Xiw} xRf=F=S(:|a*7
Է?
[/0&& qeI |ad3{x -hQx1kY>-k{rƃ^@.=
>KL                                                                            phy_process_state_change        PHY not configured. Try setting interface up    PHY already performing a test                   PHY driver does not support cable test TDR                      PHY not configured. Try setting interface up    PHY already performing a test                   PHY driver does not support cable testing                      @ @@@@@                                                                             I   E   G   H   F   Y   U   W   X   V  @
 B  @
 >  @
 @  @
 A  @
 ?  @
 T  @
 P  @
 R  @
 S  @
 Q   &   $   '   %   ;   9   <   =   :   N   K   M   O   L                  P  "  P  #  P  (  P  6  P  4  P  7  P  8  P  5  @    @    @    @    a    a     a  !   N     N    '  *  '  .  '    '    '  ,  '  -  '    '  +  '      0  	  /  	               D    )      d     d   C  d      d    Z  d   [  
     
       
   \                                                                                                                                                                                                                                                                  phy_driver_register             genphy_loopback phy_poll_reset  strnlen strscpy                                                                                                                                                                                                                                                                                                                                                                                                                                            \   C                          	   
            
         	                       __mdiobus_register                                                                                                                      mdio    mdio_driver_register            mdio_device_register             !    A@     `      `         0phy_print_status  phy_get_rate_matching  phy_restart_aneg  phy_aneg_done  phy_ethtool_ksettings_get  phy_mii_ioctl  phy_do_ioctl  phy_do_ioctl_running  phy_queue_state_machine  phy_trigger_machine  phy_ethtool_get_strings  phy_ethtool_get_sset_count  phy_ethtool_get_stats  phy_start_cable_test  phy_start_cable_test_tdr  phy_config_aneg  phy_start_aneg  phy_ethtool_ksettings_set  phy_speed_down  phy_speed_up  phy_start_machine  phy_error  phy_request_interrupt  phy_free_interrupt  phy_stop  phy_start  phy_mac_interrupt  phy_init_eee  phy_get_eee_err  phy_ethtool_get_eee  phy_ethtool_set_eee  phy_ethtool_set_wol  phy_ethtool_get_wol  phy_ethtool_get_link_ksettings  phy_ethtool_set_link_ksettings  phy_ethtool_nway_reset  genphy_c45_pma_resume  genphy_c45_pma_suspend  genphy_c45_pma_baset1_setup_master_slave  genphy_c45_pma_setup_forced  genphy_c45_an_config_aneg  genphy_c45_an_disable_aneg  genphy_c45_restart_aneg  genphy_c45_check_and_restart_aneg  genphy_c45_aneg_done  genphy_c45_read_link  genphy_c45_read_lpa  genphy_c45_pma_baset1_read_master_slave  genphy_c45_read_pma  genphy_c45_read_mdix  genphy_c45_pma_read_abilities  genphy_c45_baset1_read_status  genphy_c45_read_status  genphy_c45_config_aneg  gen10g_config_aneg  genphy_c45_loopback  genphy_c45_fast_retrain  phy_speed_to_str  phy_duplex_to_str  phy_rate_matching_to_str  phy_interface_num_ports  phy_lookup_setting  phy_set_max_speed  phy_resolve_aneg_pause  phy_resolve_aneg_linkmode  phy_check_downshift  __phy_read_mmd  phy_read_mmd  __phy_write_mmd  phy_write_mmd  phy_modify_changed  __phy_modify  phy_modify  __phy_modify_mmd_changed  phy_modify_mmd_changed  __phy_modify_mmd  phy_modify_mmd  phy_save_page  phy_select_page  phy_restore_page  phy_read_paged  phy_write_paged  phy_modify_paged_changed  phy_modify_paged  phy_basic_features  phy_basic_t1_features  phy_gbit_features  phy_gbit_fibre_features  phy_gbit_all_ports_features  phy_10gbit_features  phy_10gbit_fec_features  phy_basic_ports_array  phy_fibre_port_array  phy_all_ports_features_array  phy_10_100_features_array  phy_basic_t1_features_array  phy_gbit_features_array  phy_10gbit_features_array  phy_10gbit_full_features  phy_device_free  phy_register_fixup  phy_register_fixup_for_uid  phy_register_fixup_for_id  phy_unregister_fixup  phy_unregister_fixup_for_uid  phy_unregister_fixup_for_id  phy_device_create  fwnode_get_phy_id  get_phy_device  phy_device_register  phy_device_remove  phy_get_c45_ids  phy_find_first  phy_connect_direct  phy_connect  phy_disconnect  phy_init_hw  phy_attached_info  phy_attached_info_irq  phy_attached_print  phy_sfp_attach  phy_sfp_detach  phy_sfp_probe  phy_attach_direct  phy_attach  phy_driver_is_genphy  phy_driver_is_genphy_10g  phy_package_join  phy_package_leave  devm_phy_package_join  phy_detach  phy_suspend  __phy_resume  phy_resume  phy_loopback  phy_reset_after_clk_enable  genphy_config_eee_advert  genphy_setup_forced  genphy_read_master_slave  genphy_restart_aneg  genphy_check_and_restart_aneg  __genphy_config_aneg  genphy_c37_config_aneg  genphy_aneg_done  genphy_update_link  genphy_read_lpa  genphy_read_status_fixed  genphy_read_status  genphy_c37_read_status  genphy_soft_reset  genphy_handle_interrupt_no_ack  genphy_read_abilities  genphy_read_mmd_unsupported  genphy_write_mmd_unsupported  genphy_suspend  genphy_resume  genphy_loopback  phy_remove_link_mode  phy_advertise_supported  phy_support_sym_pause  phy_support_asym_pause  phy_set_sym_pause  phy_set_asym_pause  phy_validate_pause  phy_get_pause  phy_get_internal_delay  fwnode_mdio_find_device  fwnode_phy_find_device  device_phy_find_device  fwnode_get_phy_node  phy_driver_register  phy_drivers_register  phy_driver_unregister  phy_drivers_unregister  linkmode_resolve_pause  linkmode_set_pause  mdiobus_register_device  mdiobus_unregister_device  mdiobus_get_phy  mdiobus_is_registered_device  mdiobus_alloc_size  mdio_find_bus  __mdiobus_register  mdiobus_unregister  mdiobus_free  mdiobus_scan  __mdiobus_read  __mdiobus_write  __mdiobus_modify_changed  mdiobus_read_nested  mdiobus_read  mdiobus_write_nested  mdiobus_write  mdiobus_modify  mdiobus_modify_changed  mdio_bus_type  mdio_bus_exit  mdio_device_free  mdio_device_create  mdio_device_register  mdio_device_remove  mdio_device_reset  mdio_driver_register  mdio_driver_unregister  swphy_validate_state  swphy_read_reg  phy_led_trigger_change_speed  phy_led_triggers_register  phy_led_triggers_unregister                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  PHY state change %s -> %s
 rx/tx rx off tx (downshifted)   Link is Down
 drivers/net/phy/phy.c called from state %s
 DOWN READY HALTED UP RUNNING NOLINK CABLETEST libphy Generic Clause 45 PHY 10Mbps 100Mbps 1Gbps 2.5Gbps 5Gbps 10Gbps 14Gbps 20Gbps 25Gbps 40Gbps 50Gbps 56Gbps 100Gbps 200Gbps 400Gbps Unknown drivers/net/phy/phy-core.c Half Full none pause crs open-loop MATCH ANY PHY 0x%08x
 %d
 internal unknown %s
 0x%.8lx
 compatible ethernet-phy-id%4x.%4x failed to initialize
 failed to add
 POLL MAC %d %s %s failed: %d
 drivers/net/phy/phy_device.c phy-handle phy phy-device devm_phy_package_leave %s:%02x &dev->lock phydev attached_dev failed to get the bus module
 PHY already attached
 3libphy: PHY %s not found
  [unbound]  mii gmii sgmii tbi rev-mii rmii rev-rmii rgmii rgmii-id rgmii-rxid rgmii-txid rtbi smii xgmii xlgmii moca qsgmii trgmii 100base-x 1000base-x 2500base-x 5gbase-r rxaui xaui 10gbase-r 25gbase-r usxgmii 10gbase-kr qusgmii 1000base-kx libphy %s: Registered new driver
 phy_standalone PHY phy_dev_flags phy_has_fixups phy_interface phy_id Generic PHY drivers/net/phy/mdio_bus.c %llu
 read write reset PHY reset phy %s &bus->mdio_lock &bus->shared_lock probed
 mdio_bus statistics libphy reads_31 writes_31 errors_31 transfers_31 reads_30 writes_30 errors_30 transfers_30 reads_29 writes_29 errors_29 transfers_29 reads_28 writes_28 errors_28 transfers_28 reads_27 writes_27 errors_27 transfers_27 reads_26 writes_26 errors_26 transfers_26 reads_25 writes_25 errors_25 transfers_25 reads_24 writes_24 errors_24 transfers_24 reads_23 writes_23 errors_23 transfers_23 reads_22 writes_22 errors_22 transfers_22 reads_21 writes_21 errors_21 transfers_21 reads_20 writes_20 errors_20 transfers_20 reads_19 writes_19 errors_19 transfers_19 reads_18 writes_18 errors_18 transfers_18 reads_17 writes_17 errors_17 transfers_17 reads_16 writes_16 errors_16 transfers_16 reads_15 writes_15 errors_15 transfers_15 reads_14 writes_14 errors_14 transfers_14 reads_13 writes_13 errors_13 transfers_13 reads_12 writes_12 errors_12 transfers_12 reads_11 writes_11 errors_11 transfers_11 reads_10 writes_10 errors_10 transfers_10 reads_9 writes_9 errors_9 transfers_9 reads_8 writes_8 errors_8 transfers_8 reads_7 writes_7 errors_7 transfers_7 reads_6 writes_6 errors_6 transfers_6 reads_5 writes_5 errors_5 transfers_5 reads_4 writes_4 errors_4 transfers_4 reads_3 writes_3 errors_3 transfers_3 reads_2 writes_2 errors_2 transfers_2 reads_1 writes_1 errors_1 transfers_1 reads_0 writes_0 errors_0 transfers_0 reads writes errors transfers char[61] busid char u8 addr u16 val unsigned regnum libphy: %s: %s
 %s
 %s:%02x libphy drivers/net/phy/mdio_device.c %s: %s
 drivers/net/phy/swphy.c 4swphy: unknown speed
 link %s:%02x:%s     Link is Up - %s/%s %s- flow control %s
 Error %d requesting IRQ %d, falling back to polling
    Can't enable interrupt, falling back to polling
        Error while aborting cable test Unsupported Master/Slave mode
  Unsupported (update phy-core.c) PHY_INTERFACE_MODE_MAX isn't a valid interface mode     write_page callback not available, PHY driver not loaded?
      Downshift occurred from negotiated speed %s to actual speed %s, check cabling!
 read_page callback not available, PHY driver not loaded?
       mdio:%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u%u   error %d loading PHY driver module for ID 0x%08lx
      3libphy: %s: features and get_features must not both be set
   %s: driver must not provide a DT match table
   3libphy: %s: Error %d in registering driver
   libphy: %s: Registered new driver
      failed to get the device driver module
 could not add device link to %s err %d
 error creating 'phy_standalone' sysfs entry
    attached PHY driver %s(mii_bus:phy_addr=%s, irq=%s)
    attached PHY driver %s(mii_bus:phy_addr=%s, irq=%s)     Unsupported Master/Slave mode
  Master/Slave resolution failed, maybe conflicting manual settings?
     Master/Slave resolution failed
 %s: not in RELEASED or ALLOCATED state
 %s %-5s phy:0x%02hhx reg:0x%02x val:0x%04hx
    %s: not in UNREGISTERED state
  %s: not in ALLOCATED or UNREGISTERED state
     3libphy: mii_bus %s failed to register
        mii_bus %s couldn't get reset GPIO
     3libphy: %s: Error %d in registering driver
   3libphy: MDIO %d failed to add
        No phy led trigger registered for speed(%d)
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      (                                                                                                        (                                                                                                                           (                 (                                                                                                                                                                                                                         (  `  (                 `                                                 (                 (                         (  0  (                   0                                                                                   (    0  8  @  8  0  (                     @  8  0  (                           @  8  0  (                     @  8  0  (                     @                          0          0                         (  0  H  0  (                   H                                                            8               8                                                                 (  0  @  0  (                   @                       (                 (                       (                     @  (                                                                                                                                         (                 (                                                                                                                                                                                           (                 (                 (                                                                                                                                                                             (                                                                                         8               8                         (  0  (                         0  (                   0  (                   0                                                                                            (                                                                   (                                                (                                                             (            (            (                         (                       (                 (                                        (  0  (                   0  (                                                                     (                 (                         (  0  (                   0                   (    0  8  0  (                     8                         (    0  8  0  (                     8                         (  0  (                                          (    0  8  0  (                     8                         (    0  8  0  (                                                                 (            (          8                                                                               (               (                            (    0  8  0  (                     8                                                                                                           (  0  8  @  H  P  X  `  h  p  x                                                             0          0                                                                                                                                                                                                                                       (                                                                          (                 (                     @               @                                                                                                                               (                 (                                                                                         (    0  8  0  (                     8  0  (                                                                                                                                                                                                (               (                                      (    0  8  0  (                     8                                                                                               (    0  8  @  8  0  (                     @                         (  0  (                   0  (                   0                   (    0  8  @  8  0  (                     @                                                                                                                                                               (    0  8  @  8  0  (                     @                                                           (                                        (  0  (                   0  (                   0  (                   0                                                               (                 (                                                                                                                                                                                                                                                                                                                                0          0                0          0                0          0                               8               8                         (    0  8  @  8  0  (                     @  8  0  (                     @                       (    (                                  8  @  (  0                                                                            (  @  (                 @                         (    0  8  @  H  @  8  0  (                                                                                                                                                                                                                                                                                                                                                            (  0  (                   0  8  0  (                   0                       (                                      (                                        (    0  8  x  8  0  (                     x                                                                   (                                        (  0  (                   0  (                   0  (                   0                         (    0  8  0  (                     8  @  8  0  (                     8                         (  0  (                   0  (                                          (  0  (                                          (  0  (                                          (    0  8  @  8  0  (                     @                         (    0  8  @  8  0  (                                           0                                                                                                                                                                                                                                                                                                                                                                                                   (  0    0  (                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 