home | help
std::equal(3)		       C++ Standard Libary		   std::equal(3)

NAME
     std::equal - std::equal

Synopsis
	Defined in header <algorithm>
	template< class InputIt1, class InputIt2 >

	bool  equal( InputIt1 first1, InputIt1 last1,		  (1) (constexpr
     since C++20)

		    InputIt2 first2 );
	template< class ExecutionPolicy, class ForwardIt1, class
	ForwardIt2 >

	bool  equal(  ExecutionPolicy&&  policy,		     (2)  (since
     C++17)
		    ForwardIt1 first1, ForwardIt1 last1,

		    ForwardIt2 first2 );
	template< class InputIt1, class InputIt2, class
	BinaryPred >
								 (3)  (constexpr
     since C++20)
	bool equal( InputIt1 first1, InputIt1 last1,

		    InputIt2 first2, BinaryPred p );
	template< class ExecutionPolicy,

		  class ForwardIt1, class ForwardIt2, class
	BinaryPred  >						    (4)   (since
     C++17)
	bool equal( ExecutionPolicy&& policy,
		    ForwardIt1 first1, ForwardIt1 last1,

		    ForwardIt2 first2, BinaryPred p );
	template< class InputIt1, class InputIt2 >
								     (since
     C++14)
	bool  equal( InputIt1 first1, InputIt1 last1,		  (5) (constexpr
     since C++20)

		    InputIt2 first2, InputIt2 last2 );
	template< class ExecutionPolicy, class ForwardIt1, class
	ForwardIt2 >

	bool  equal(  ExecutionPolicy&&  policy,		     (6)  (since
     C++17)
		    ForwardIt1 first1, ForwardIt1 last1,

		    ForwardIt2 first2, ForwardIt2 last2 );
	template< class InputIt1, class InputIt2, class
	BinaryPred >
								     (since
     C++14)
	bool  equal( InputIt1 first1, InputIt1 last1,		  (7) (constexpr
     since C++20)

		    InputIt2 first2, InputIt2 last2, BinaryPred
	p );
	template< class ExecutionPolicy,

		  class ForwardIt1, class ForwardIt2, class
	BinaryPred >
	bool  equal(  ExecutionPolicy&&  policy,		     (8)  (since
     C++17)
		    ForwardIt1 first1, ForwardIt1 last1,

		    ForwardIt2 first2, ForwardIt2 last2,
	BinaryPred p );

	Checks	whether  [first1,  last1)  and	a range starting from first2 are
     equal:

	  * For overloads (1-4),  the  second  range  has  std::distance(first1,
     last1) elements.
	  * For overloads (5-8), the second range is [first2, last2).
	1,5) Elements are compared using operator==.
	3,7) Elements are compared using the given binary predicate p.
	2,4,6,8) Same as (1,3,5,7), but executed according to policy.
	These overloads participate in overload resolution only if

	std::is_execution_policy_v<std::decay_t<ExecutionPolicy>>    is    true.
     (until
										  C++20)
	std::is_execution_policy_v<std::remove_cvref_t<ExecutionPolicy>>      is
     true. (since
										  C++20)

Parameters
	first1, last1 - the first range of the elements to compare
	first2, last2 - the second range of the elements to compare
	policy	       -  the  execution policy to use. See execution policy for
     details.
			binary predicate which	returns  true  if  the	elements
     should be
			treated as equal.

			The signature of the predicate function should be equiv-
     alent to the
			following:

			 bool pred(const Type1 &a, const Type2 &b);

	p	       -  While the signature does not need to have const &, the
     function must
			not modify the objects passed to it and must be able  to
     accept all
			values	of type (possibly const) Type1 and Type2 regard-
     less of value
			category (thus, Type1 & is not allowed
			, nor is Type1 unless for Type1 a move is equivalent  to
     a copy
			(since C++11)).
			The  types  Type1 and Type2 must be such that objects of
     types
			InputIt1 and InputIt2 can be dereferenced and  then  im-
     plicitly
			converted to Type1 and Type2 respectively.

Type requirements
	-
	InputIt1, InputIt2 must meet the requirements of LegacyInputIterator.
	-
	ForwardIt1, ForwardIt2 must meet the requirements of LegacyForwardItera-
     tor.
	-
	BinaryPred must meet the requirements of BinaryPredicate.

Return value
	1-4) If each corresponding elements in the two ranges are equal, returns
     true.
	Otherwise returns false.
	5-8)  If  std::distance(first1,  last1) and std::distance(first2, last2)
     are equal, and
	each corresponding elements in the two ranges are equal,  returns  true.
     Otherwise
	returns false.

Complexity
	Given \(\scriptsize N_1\)N
	1 as std::distance(first1, last1) and \(\scriptsize N_2\)N
	2 as std::distance(first2, last2):

	1) At most \(\scriptsize N_1\)N
	1 comparisons using operator==.
	2) \(\scriptsize O(N_1)\)O(N
	1) comparisons using operator==.
	3) At most \(\scriptsize N_1\)N
	1 applications of the predicate p.
	4) \(\scriptsize O(N_1)\)O(N
	1) applications of the predicate p.
	5-8)  If  InputIt1 and InputIt2 are both LegacyRandomAccessIterator, and
     last1 -
	first1 != last2 - first2 is true, no comparison will be made.
	Otherwise,     given	 \(\scriptsize	   N\)N     as	   \(\scriptsize
     \min(N_1,N_2)\)min(N
	1,N
	2):
	5) At most \(\scriptsize N\)N comparisons using operator==.
	6) \(\scriptsize O(N)\)O(N) comparisons using operator==.
	7) At most \(\scriptsize N\)N applications of the predicate p.
	8) \(\scriptsize O(N)\)O(N) applications of the predicate p.

Exceptions
	The overloads with a template parameter named ExecutionPolicy report er-
     rors as
	follows:

	  *  If  execution of a function invoked as part of the algorithm throws
     an exception
	    and ExecutionPolicy is one of the standard policies,  std::terminate
     is called.
	    For  any  other  ExecutionPolicy, the behavior is implementation-de-
     fined.
	  * If the algorithm fails to allocate memory, std::bad_alloc is thrown.

Possible implementation
					     equal (1)
	template<class InputIt1, class InputIt2>
	constexpr //< since C++20
	bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
	{
	    for (; first1 != last1; ++first1, ++first2)
		if (!(*first1 == *first2))
		    return false;

	    return true;
	}
					     equal (3)
	template<class InputIt1, class InputIt2, class BinaryPred>
	constexpr //< since C++20
	bool equal(InputIt1 first1, InputIt1 last1,
		   InputIt2 first2, BinaryPred p)
	{
	    for (; first1 != last1; ++first1, ++first2)
		if (!p(*first1, *first2))
		    return false;

	    return true;
	}
					     equal (5)
	namespace detail
	{
	    // random-access iterator implementation (allows  quick  range  size
     detection)
	    template<class RandomIt1, class RandomIt2>
	    constexpr //< since C++20
	    bool equal(RandomIt1 first1, RandomIt1 last1, RandomIt2 first2, Ran-
     domIt2 last2,
		       std::random_access_iterator_tag, std::random_access_iter-
     ator_tag)
	    {
		if (last1 - first1 != last2 - first2)
		    return false;

		for (; first1 != last1; ++first1, ++first2)
		    if (!(*first1 == *first2))
			return false;

		return true;
	    }

	    //	input  iterator  implementation  (needs to manually compare with
     alast2a)
	    template<class InputIt1, class InputIt2>
	    constexpr //< since C++20
	    bool equal(InputIt1 first1, InputIt1  last1,  InputIt2  first2,  In-
     putIt2 last2,
		       std::input_iterator_tag, std::input_iterator_tag)
	    {
		for (; first1 != last1 && first2 != last2; ++first1, ++first2)
		    if (!(*first1 == *first2))
			return false;

		return first1 == last1 && first2 == last2;
	    }
	}

	template<class InputIt1, class InputIt2>
	constexpr //< since C++20
	bool  equal(InputIt1  first1,  InputIt1 last1, InputIt2 first2, InputIt2
     last2)
	{
	    details::equal(first1, last1, first2, last2,
			   typename	  std::iterator_traits<InputIt1>::itera-
     tor_category(),
			   typename	  std::iterator_traits<InputIt2>::itera-
     tor_category());
	}
					     equal (7)
	namespace detail
	{
	    // random-access iterator implementation (allows  quick  range  size
     detection)
	    template<class RandomIt1, class RandomIt2, class BinaryPred>
	    constexpr //< since C++20
	    bool equal(RandomIt1 first1, RandomIt1 last1,
		       RandomIt2 first2, RandomIt2 last2, BinaryPred p,
		       std::random_access_iterator_tag, std::random_access_iter-
     ator_tag)
	    {
		if (last1 - first1 != last2 - first2)
		    return false;

		for (; first1 != last1; ++first1, ++first2)
		    if (!p(*first1, *first2))
			return false;

		return true;
	    }

	    //	input  iterator  implementation  (needs to manually compare with
     alast2a)
	    template<class InputIt1, class InputIt2, class BinaryPred>
	    constexpr //< since C++20
	    bool equal(InputIt1 first1, InputIt1 last1,
		       InputIt2 first2, InputIt2 last2, BinaryPred p,
		       std::input_iterator_tag, std::input_iterator_tag)
	    {
		for (; first1 != last1 && first2 != last2; ++first1, ++first2)
		    if (!p(*first1, *first2))
			return false;

		return first1 == last1 && first2 == last2;
	    }
	}

	template<class InputIt1, class InputIt2, class BinaryPred>
	constexpr //< since C++20
	bool equal(InputIt1 first1, InputIt1 last1,
		   InputIt2 first2, InputIt2 last2, BinaryPred p)
	{
	    details::equal(first1, last1, first2, last2, p,
			   typename	  std::iterator_traits<InputIt1>::itera-
     tor_category(),
			   typename	  std::iterator_traits<InputIt2>::itera-
     tor_category());
	}

Notes
	std::equal should not be used to compare the ranges formed by the itera-
     tors from
	std::unordered_set, std::unordered_multiset, std::unordered_map, or
	std::unordered_multimap because the order  in  which  the  elements  are
     stored in those
	containers  may  be  different even if the two containers store the same
     elements.

	When comparing entire containers for equality, operator== for the corre-
     sponding
	container are usually preferred.

Example
	The following code uses std::equal to test if a string is a palindrome.

     // Run this code

      #include <algorithm>
      #include <iomanip>
      #include <iostream>
      #include <string_view>

      constexpr bool is_palindrome(const std::string_view& s)
      {
	  return std::equal(s.cbegin(), s.cbegin() + s.size() / 2, s.crbegin());
      }

      void test(const std::string_view& s)
      {
	  std::cout << std::quoted(s)
		    << (is_palindrome(s) ? " is" : " is not")
		    << " a palindrome\n";
      }

      int main()
      {
	  test("radar");
	  test("hello");
      }

Output:
      "radar" is a palindrome
      "hello" is not a palindrome

See also
	find
	find_if 		finds the first element satisfying specific cri-
     teria
	find_if_not		(function template)
	(C++11)
				returns true if one range  is  lexicographically
     less than
	lexicographical_compare another
				(function template)
	mismatch		finds the first position where two ranges differ
				(function template)
	search			searches for a range of elements
				(function template)
	ranges::equal		determines if two sets of elements are the same
	(C++20) 		(niebloid)
	equal_to		function object implementing x == y
				(class template)
	equal_range		 returns  range  of elements matching a specific
     key
				(function template)

http://cppreference.com 	   2024.06.10			   std::equal(3)

home | help