forked from mirrors/gecko-dev
		
	 2e065c64d6
			
		
	
	
		2e065c64d6
		
	
	
	
	
		
			
			Among other things, there were some misuses of std::forward, and GenericErrorResult was (presumably accidentally) instatiated with references as the template argument type, e.g. const nsresult&, which circumvented the check for not calling it with NS_OK in ResultExtensions.h Differential Revision: https://phabricator.services.mozilla.com/D90561
		
			
				
	
	
		
			109 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			109 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #ifndef ArrayAlgorithm_h___
 | |
| #define ArrayAlgorithm_h___
 | |
| 
 | |
| #include "nsTArray.h"
 | |
| 
 | |
| #include "mozilla/Algorithm.h"
 | |
| #include "mozilla/ResultExtensions.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| // An algorithm similar to TransformAbortOnErr, which creates a new nsTArray
 | |
| // rather than inserting into an output iterator. The capacity of the result
 | |
| // array is set to the number of elements that will be inserted if all
 | |
| // transformations are successful. This variant is fallible, i.e. if setting the
 | |
| // capacity fails, NS_ERROR_OUT_OF_MEMORY is returned as an error value. This
 | |
| // variant only works with nsresult errors.
 | |
| template <
 | |
|     typename SrcIter, typename Transform,
 | |
|     typename = std::enable_if_t<std::is_same_v<
 | |
|         typename detail::TransformTraits<Transform, SrcIter>::result_err_type,
 | |
|         nsresult>>>
 | |
| Result<nsTArray<typename detail::TransformTraits<Transform,
 | |
|                                                  SrcIter>::result_ok_type>,
 | |
|        nsresult>
 | |
| TransformIntoNewArrayAbortOnErr(SrcIter aIter, SrcIter aEnd,
 | |
|                                 Transform aTransform, fallible_t) {
 | |
|   nsTArray<typename detail::TransformTraits<Transform, SrcIter>::result_ok_type>
 | |
|       res;
 | |
|   if (!res.SetCapacity(std::distance(aIter, aEnd), fallible)) {
 | |
|     return Err(NS_ERROR_OUT_OF_MEMORY);
 | |
|   }
 | |
| 
 | |
|   auto transformRes = TransformAbortOnErr(aIter, aEnd, MakeBackInserter(res),
 | |
|                                           std::move(aTransform));
 | |
|   if (NS_WARN_IF(transformRes.isErr())) {
 | |
|     return Err(transformRes.unwrapErr());
 | |
|   }
 | |
| 
 | |
|   return res;
 | |
| }
 | |
| 
 | |
| template <typename SrcRange, typename Transform>
 | |
| auto TransformIntoNewArrayAbortOnErr(SrcRange& aRange, Transform aTransform,
 | |
|                                      fallible_t) {
 | |
|   using std::begin;
 | |
|   using std::end;
 | |
|   return TransformIntoNewArrayAbortOnErr(begin(aRange), end(aRange), aTransform,
 | |
|                                          fallible);
 | |
| }
 | |
| 
 | |
| // An algorithm similar to std::transform, which creates a new nsTArray
 | |
| // rather than inserting into an output iterator. The capacity of the result
 | |
| // array is set to the number of elements that will be inserted. This variant is
 | |
| // fallible, i.e. if setting the capacity fails, NS_ERROR_OUT_OF_MEMORY is
 | |
| // returned as an error value. This variant only works with nsresult errors.
 | |
| template <typename SrcIter, typename Transform>
 | |
| Result<nsTArray<detail::ArrayElementTransformType<Transform, SrcIter>>,
 | |
|        nsresult>
 | |
| TransformIntoNewArray(SrcIter aIter, SrcIter aEnd, Transform aTransform,
 | |
|                       fallible_t) {
 | |
|   nsTArray<detail::ArrayElementTransformType<Transform, SrcIter>> res;
 | |
|   if (!res.SetCapacity(std::distance(aIter, aEnd), fallible)) {
 | |
|     return Err(NS_ERROR_OUT_OF_MEMORY);
 | |
|   }
 | |
| 
 | |
|   std::transform(aIter, aEnd, MakeBackInserter(res), std::move(aTransform));
 | |
| 
 | |
|   return res;
 | |
| }
 | |
| 
 | |
| template <typename SrcRange, typename Transform>
 | |
| auto TransformIntoNewArray(SrcRange& aRange, Transform aTransform, fallible_t) {
 | |
|   using std::begin;
 | |
|   using std::end;
 | |
|   return TransformIntoNewArray(begin(aRange), end(aRange), aTransform,
 | |
|                                fallible);
 | |
| }
 | |
| 
 | |
| // An algorithm similar to std::transform, which creates a new nsTArray
 | |
| // rather than inserting into an output iterator. The capacity of the result
 | |
| // array is set to the number of elements that will be inserted. This variant is
 | |
| // infallible, i.e. if setting the capacity fails, the process is aborted.
 | |
| template <typename SrcIter, typename Transform>
 | |
| nsTArray<detail::ArrayElementTransformType<Transform, SrcIter>>
 | |
| TransformIntoNewArray(SrcIter aIter, SrcIter aEnd, Transform aTransform) {
 | |
|   nsTArray<detail::ArrayElementTransformType<Transform, SrcIter>> res;
 | |
|   res.SetCapacity(std::distance(aIter, aEnd));
 | |
| 
 | |
|   std::transform(aIter, aEnd, MakeBackInserter(res), std::move(aTransform));
 | |
| 
 | |
|   return res;
 | |
| }
 | |
| 
 | |
| template <typename SrcRange, typename Transform>
 | |
| auto TransformIntoNewArray(SrcRange& aRange, Transform aTransform) {
 | |
|   using std::begin;
 | |
|   using std::end;
 | |
|   return TransformIntoNewArray(begin(aRange), end(aRange), aTransform);
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla
 | |
| 
 | |
| #endif  // !defined(ArrayAlgorithm_h___)
 |