1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef ArrayAlgorithm_h___
8 #define ArrayAlgorithm_h___
12 #include "mozilla/Algorithm.h"
13 #include "mozilla/ResultExtensions.h"
17 // An algorithm similar to TransformAbortOnErr, which creates a new nsTArray
18 // rather than inserting into an output iterator. The capacity of the result
19 // array is set to the number of elements that will be inserted if all
20 // transformations are successful. This variant is fallible, i.e. if setting the
21 // capacity fails, NS_ERROR_OUT_OF_MEMORY is returned as an error value. This
22 // variant only works with nsresult errors.
24 typename SrcIter
, typename Transform
,
25 typename
= std::enable_if_t
<std::is_same_v
<
26 typename
detail::TransformTraits
<Transform
, SrcIter
>::result_err_type
,
28 Result
<nsTArray
<typename
detail::TransformTraits
<Transform
,
29 SrcIter
>::result_ok_type
>,
31 TransformIntoNewArrayAbortOnErr(SrcIter aIter
, SrcIter aEnd
,
32 Transform aTransform
, fallible_t
) {
33 nsTArray
<typename
detail::TransformTraits
<Transform
, SrcIter
>::result_ok_type
>
35 if (!res
.SetCapacity(std::distance(aIter
, aEnd
), fallible
)) {
36 return Err(NS_ERROR_OUT_OF_MEMORY
);
39 auto transformRes
= TransformAbortOnErr(aIter
, aEnd
, MakeBackInserter(res
),
40 std::move(aTransform
));
41 if (NS_WARN_IF(transformRes
.isErr())) {
42 return Err(transformRes
.unwrapErr());
48 template <typename SrcRange
, typename Transform
>
49 auto TransformIntoNewArrayAbortOnErr(SrcRange
& aRange
, Transform aTransform
,
53 return TransformIntoNewArrayAbortOnErr(begin(aRange
), end(aRange
), aTransform
,
57 // An algorithm similar to std::transform, which creates a new nsTArray
58 // rather than inserting into an output iterator. The capacity of the result
59 // array is set to the number of elements that will be inserted. This variant is
60 // fallible, i.e. if setting the capacity fails, NS_ERROR_OUT_OF_MEMORY is
61 // returned as an error value. This variant only works with nsresult errors.
62 template <typename SrcIter
, typename Transform
>
63 Result
<nsTArray
<detail::ArrayElementTransformType
<Transform
, SrcIter
>>,
65 TransformIntoNewArray(SrcIter aIter
, SrcIter aEnd
, Transform aTransform
,
67 nsTArray
<detail::ArrayElementTransformType
<Transform
, SrcIter
>> res
;
68 if (!res
.SetCapacity(std::distance(aIter
, aEnd
), fallible
)) {
69 return Err(NS_ERROR_OUT_OF_MEMORY
);
72 std::transform(aIter
, aEnd
, MakeBackInserter(res
), std::move(aTransform
));
77 template <typename SrcRange
, typename Transform
>
78 auto TransformIntoNewArray(SrcRange
& aRange
, Transform aTransform
, fallible_t
) {
81 return TransformIntoNewArray(begin(aRange
), end(aRange
), aTransform
,
85 // An algorithm similar to std::transform, which creates a new nsTArray
86 // rather than inserting into an output iterator. The capacity of the result
87 // array is set to the number of elements that will be inserted. This variant is
88 // infallible, i.e. if setting the capacity fails, the process is aborted.
89 template <typename SrcIter
, typename Transform
>
90 nsTArray
<detail::ArrayElementTransformType
<Transform
, SrcIter
>>
91 TransformIntoNewArray(SrcIter aIter
, SrcIter aEnd
, Transform aTransform
) {
92 nsTArray
<detail::ArrayElementTransformType
<Transform
, SrcIter
>> res
;
93 res
.SetCapacity(std::distance(aIter
, aEnd
));
95 std::transform(aIter
, aEnd
, MakeBackInserter(res
), std::move(aTransform
));
100 template <typename SrcRange
, typename Transform
>
101 auto TransformIntoNewArray(SrcRange
& aRange
, Transform aTransform
) {
104 return TransformIntoNewArray(begin(aRange
), end(aRange
), aTransform
);
107 } // namespace mozilla
109 #endif // !defined(ArrayAlgorithm_h___)