Skip to content

Commit

Permalink
Support comma operator in subscripting expressions of lambda introducer
Browse files Browse the repository at this point in the history
  • Loading branch information
ken-matsui committed Dec 7, 2020
1 parent abbe03e commit 185f30d
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 13 deletions.
39 changes: 28 additions & 11 deletions include/mitama/result/result.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1774,21 +1774,38 @@ class [[nodiscard]] basic_result<_mutability, T, E,
} // namespace mitama

// MSVC does not implement compound statements (ref: https://stackoverflow.com/q/5291532)
#if defined(__GNUC__) || defined(__clang__)
#if defined(__clang__) || defined(__GNUC__)
# define MITAMA_CPP_RESULT_TRY_MAY_NOT_PANIC true
# define MITAMA_TRY( RESULT ) \
({ \
const auto result = RESULT; \
if (result.is_err()) { \
using Err = mitama::failure_t<decltype(result)::err_type>; \
return std::get<Err>(result.into_storage()); \
} \
using Ok = mitama::success_t<decltype(result)::ok_type>; \
std::get<Ok>(result.into_storage()).get(); \
# define MITAMA_TRY_IMPL( ... ) \
({ \
auto&& result = [&]()->decltype(auto){ return (__VA_ARGS__); }(); \
static_assert( \
::mitama::is_result_v<::mitama::meta::remove_cvr_t<decltype(result)>>, \
"You should pass mitama::result type to this MITAMA_TRY macro." \
); \
if (result.is_err()) { \
using Err = ::mitama::failure_t< \
::mitama::meta::remove_cvr_t<decltype(result)>::err_type \
>; \
return ::std::get<Err>(result.into_storage()); \
} \
using Ok = ::mitama::success_t< \
::mitama::meta::remove_cvr_t<decltype(result)>::ok_type \
>; \
::std::get<Ok>(result.into_storage()).get(); \
})
# ifdef __clang__
# define MITAMA_TRY( ... ) \
_Pragma("GCC diagnostic push") \
_Pragma("GCC diagnostic ignored \"-Wgnu-statement-expression\"") \
MITAMA_TRY_IMPL(__VA_ARGS__) \
_Pragma("GCC diagnostic pop")
# else
# define MITAMA_TRY( ... ) MITAMA_TRY_IMPL(__VA_ARGS__)
# endif
#else
# define MITAMA_CPP_RESULT_TRY_MAY_NOT_PANIC false
# define MITAMA_TRY( RESULT ) RESULT.unwrap()
# define MITAMA_TRY( ... ) (__VA_ARGS__).unwrap()
#endif

#endif
7 changes: 5 additions & 2 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,11 @@ message($CMAKE)
foreach(TEST_NAME ${TEST_NAMES})
add_executable(${TEST_NAME} ${TEST_NAME}.cpp)
target_compile_features(${TEST_NAME} PRIVATE cxx_std_17)
target_compile_options(${TEST_NAME} PRIVATE -Wall -Wextra -pedantic-errors -ftemplate-backtrace-limit=0)
# -Wall -Wextra -Werror -pedantic-errors
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
target_compile_options(${TEST_NAME} PRIVATE -Wall -Wextra -ftemplate-backtrace-limit=0)
else()
target_compile_options(${TEST_NAME} PRIVATE -Wall -Wextra -pedantic-errors -ftemplate-backtrace-limit=0)
endif()

if(APPLE)
target_compile_definitions(${TEST_NAME} PRIVATE _GNU_SOURCE)
Expand Down
21 changes: 21 additions & 0 deletions test/result_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1285,3 +1285,24 @@ TEST_CASE("map & map_err with void", "[result][map][map_err][void]"){
REQUIRE(y.is_ok() == true);
REQUIRE(val == 6);
}

TEST_CASE("MITAMA_TRY", "[result][mitama_try]"){
auto func =
[]() -> result<u32, str> {
result<u32, str> a = success(1);
u32 b = 2, c = 3;
u32 d = MITAMA_TRY(
[&a, &b, &c]() -> ::result<u32, str> {
return a.map(
[&b, &c](u32 x) -> u32 { return x + b + c; }
);
}()
);
return success(d);
};

result<u32, str> x = func();
REQUIRE(MITAMA_CPP_RESULT_TRY_MAY_NOT_PANIC == true);
REQUIRE(x.is_ok() == true);
REQUIRE(x.unwrap() == 6);
}

0 comments on commit 185f30d

Please sign in to comment.