Skip to content
Snippets Groups Projects
Commit f40c7497 authored by Nick Fitzgerald's avatar Nick Fitzgerald
Browse files

Bug 1324828 - Add the `mozilla::Result::map` method; r=froydnj

parent 4acbc70a
No related branches found
No related tags found
No related merge requests found
......@@ -220,6 +220,37 @@ public:
MOZ_ASSERT(isErr());
return mImpl.unwrapErr();
}
/**
* Map a function V -> W over this result's success variant. If this result is
* an error, do not invoke the function and return a copy of the error.
*
* Mapping over success values invokes the function to produce a new success
* value:
*
* // Map Result<int, E> to another Result<int, E>
* Result<int, E> res(5);
* Result<int, E> res2 = res.map([](int x) { return x * x; });
* MOZ_ASSERT(res2.unwrap() == 25);
*
* // Map Result<const char*, E> to Result<size_t, E>
* Result<const char*, E> res("hello, map!");
* Result<size_t, E> res2 = res.map(strlen);
* MOZ_ASSERT(res2.unwrap() == 11);
*
* Mapping over an error does not invoke the function and copies the error:
*
* Result<V, int> res(5);
* MOZ_ASSERT(res.isErr());
* Result<W, int> res2 = res.map([](V v) { ... });
* MOZ_ASSERT(res2.isErr());
* MOZ_ASSERT(res2.unwrapErr() == 5);
*/
template<typename F>
auto map(F f) const -> Result<decltype(f(*((V*) nullptr))), E> {
using RetResult = Result<decltype(f(*((V*) nullptr))), E>;
return isOk() ? RetResult(f(unwrap())) : RetResult(unwrapErr());
}
};
/**
......
......@@ -4,6 +4,7 @@
* 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/. */
#include <string.h>
#include "mozilla/Result.h"
using mozilla::GenericErrorResult;
......@@ -160,6 +161,45 @@ ReferenceTest()
MOZ_RELEASE_ASSERT(&res.unwrapErr() == &merror);
}
static void
MapTest()
{
struct MyError {
int x;
explicit MyError(int y) : x(y) { }
};
// Mapping over success values.
Result<int, MyError> res(5);
bool invoked = false;
auto res2 = res.map([&invoked](int x) {
MOZ_RELEASE_ASSERT(x == 5);
invoked = true;
return "hello";
});
MOZ_RELEASE_ASSERT(res2.isOk());
MOZ_RELEASE_ASSERT(invoked);
MOZ_RELEASE_ASSERT(strcmp(res2.unwrap(), "hello") == 0);
// Mapping over error values.
MyError err(1);
Result<char, MyError> res3(err);
MOZ_RELEASE_ASSERT(res3.isErr());
Result<char, MyError> res4 = res3.map([](int x) {
MOZ_RELEASE_ASSERT(false);
return 'a';
});
MOZ_RELEASE_ASSERT(res4.isErr());
MOZ_RELEASE_ASSERT(res4.unwrapErr().x == err.x);
// Function pointers instead of lamdbas as the mapping function.
Result<const char*, MyError> res5("hello");
auto res6 = res5.map(strlen);
MOZ_RELEASE_ASSERT(res6.isOk());
MOZ_RELEASE_ASSERT(res6.unwrap() == 5);
}
/* * */
int main()
......@@ -168,5 +208,6 @@ int main()
TypeConversionTests();
EmptyValueTest();
ReferenceTest();
MapTest();
return 0;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment