issue0203.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. /* Unit testing for outcomes
  2. (C) 2013-2019 Niall Douglas <http://www.nedproductions.biz/> (1 commit)
  3. Boost Software License - Version 1.0 - August 17th, 2003
  4. Permission is hereby granted, free of charge, to any person or organization
  5. obtaining a copy of the software and accompanying documentation covered by
  6. this license (the "Software") to use, reproduce, display, distribute,
  7. execute, and transmit the Software, and to prepare derivative works of the
  8. Software, and to permit third-parties to whom the Software is furnished to
  9. do so, all subject to the following:
  10. The copyright notices in the Software and this entire statement, including
  11. the above license grant, this restriction and the following disclaimer,
  12. must be included in all copies of the Software, in whole or in part, and
  13. all derivative works of the Software, unless such copies or derivative
  14. works are solely in the form of machine-executable object code generated by
  15. a source language processor.
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
  19. SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
  20. FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
  21. ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  22. DEALINGS IN THE SOFTWARE.
  23. */
  24. #include <boost/outcome/std_result.hpp>
  25. #include <boost/outcome/try.hpp>
  26. #include <boost/test/unit_test.hpp>
  27. #include <boost/test/unit_test_monitor.hpp>
  28. namespace outcome = BOOST_OUTCOME_V2_NAMESPACE;
  29. enum class error
  30. {
  31. test,
  32. abcde
  33. };
  34. class error_category_impl : public std::error_category
  35. {
  36. public:
  37. const char *name() const noexcept override { return "test"; }
  38. std::string message(int code) const noexcept override
  39. {
  40. switch(static_cast<error>(code))
  41. {
  42. case error::test:
  43. return "test";
  44. case error::abcde:
  45. return "abcde";
  46. }
  47. return "unknown";
  48. }
  49. };
  50. const std::error_category &error_category() noexcept
  51. {
  52. static error_category_impl instance;
  53. return instance;
  54. }
  55. boost::system::error_code make_error_code(error error) noexcept
  56. {
  57. return {static_cast<int>(error), error_category()};
  58. }
  59. namespace std
  60. {
  61. template <> struct is_error_code_enum<error> : true_type
  62. {
  63. };
  64. } // namespace std
  65. template <typename T> using enum_result = outcome::basic_result<T, error, outcome::policy::default_policy<T, error, void>>;
  66. enum_result<int> test()
  67. {
  68. return 5;
  69. }
  70. outcome::std_result<int> abc()
  71. {
  72. static_assert(std::is_error_code_enum<error>::value, "custom enum is not marked convertible to error code");
  73. static_assert(std::is_constructible<boost::system::error_code, error>::value, "error code is not explicitly constructible from custom enum");
  74. static_assert(std::is_convertible<error, boost::system::error_code>::value, "error code is not implicitly constructible from custom enum");
  75. boost::system::error_code ec = error::test; // custom enum is definitely convertible to error code
  76. BOOST_OUTCOME_TRY(test()); // hence this should compile, as implicit conversions work here
  77. (void) ec;
  78. // But explicit conversions are required between dissimilar basic_result, implicit conversions are disabled
  79. static_assert(std::is_constructible<outcome::std_result<int>, enum_result<int>>::value, "basic_result with error code is not explicitly constructible from basic_result with custom enum");
  80. static_assert(!std::is_convertible<enum_result<int>, outcome::std_result<int>>::value, "basic_result with error code is implicitly constructible from basic_result with custom enum");
  81. return 5;
  82. }
  83. BOOST_OUTCOME_AUTO_TEST_CASE(issues_0203_test, "enum convertible to error code works as designed")
  84. {
  85. BOOST_CHECK(abc().value() == 5);
  86. }