123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169 |
- /* Unit testing for outcomes
- (C) 2017-2019 Niall Douglas <http://www.nedproductions.biz/> (7 commits)
- Boost Software License - Version 1.0 - August 17th, 2003
- Permission is hereby granted, free of charge, to any person or organization
- obtaining a copy of the software and accompanying documentation covered by
- this license (the "Software") to use, reproduce, display, distribute,
- execute, and transmit the Software, and to prepare derivative works of the
- Software, and to permit third-parties to whom the Software is furnished to
- do so, all subject to the following:
- The copyright notices in the Software and this entire statement, including
- the above license grant, this restriction and the following disclaimer,
- must be included in all copies of the Software, in whole or in part, and
- all derivative works of the Software, unless such copies or derivative
- works are solely in the form of machine-executable object code generated by
- a source language processor.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
- SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
- FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- */
- #include <boost/outcome/experimental/status_result.hpp>
- #include <climits> // for INT_MAX
- #include <cstdio>
- // status_code<erased<intptr_t>>
- using error = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::error;
- // Outcome's result must be told when it is dealing with an erased status code
- template <class T, class E> using result = BOOST_OUTCOME_V2_NAMESPACE::experimental::status_result<T, E, BOOST_OUTCOME_V2_NAMESPACE::policy::all_narrow>;
- enum class arithmetic_errc
- {
- success,
- divide_by_zero,
- integer_divide_overflows,
- not_integer_division
- };
- class _arithmetic_errc_domain;
- using arithmetic_errc_error = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<_arithmetic_errc_domain>;
- class _arithmetic_errc_domain : public BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code_domain
- {
- using _base = BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code_domain;
- public:
- using value_type = arithmetic_errc;
- constexpr explicit _arithmetic_errc_domain(typename _base::unique_id_type id = 0x290f170194f0c6c7) noexcept : _base(id) {}
- static inline constexpr const _arithmetic_errc_domain &get();
- virtual _base::string_ref name() const noexcept override final // NOLINT
- {
- static string_ref v("arithmetic error domain");
- return v; // NOLINT
- }
- protected:
- virtual bool _do_failure(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override final // NOLINT
- {
- assert(code.domain() == *this); // NOLINT
- const auto &c1 = static_cast<const arithmetic_errc_error &>(code); // NOLINT
- return c1.value() != arithmetic_errc::success;
- }
- virtual bool _do_equivalent(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &, const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &) const noexcept override final { return false; } // NOLINT
- virtual BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::generic_code _generic_code(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &) const noexcept override final { return {}; } // NOLINT
- virtual _base::string_ref _do_message(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &code) const noexcept override final // NOLINT
- {
- assert(code.domain() == *this); // NOLINT
- const auto &c1 = static_cast<const arithmetic_errc_error &>(code); // NOLINT
- switch(c1.value())
- {
- case arithmetic_errc::success:
- return _base::string_ref("success");
- case arithmetic_errc::divide_by_zero:
- return _base::string_ref("divide by zero");
- case arithmetic_errc::integer_divide_overflows:
- return _base::string_ref("integer divide overflows");
- case arithmetic_errc::not_integer_division:
- return _base::string_ref("not integer division");
- }
- return _base::string_ref("unknown");
- }
- BOOST_OUTCOME_SYSTEM_ERROR2_NORETURN virtual void _do_throw_exception(const BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::status_code<void> &) const override final { abort(); } // NOLINT
- };
- constexpr _arithmetic_errc_domain arithmetic_errc_domain;
- inline constexpr const _arithmetic_errc_domain &_arithmetic_errc_domain::get()
- {
- return arithmetic_errc_domain;
- }
- // Tell status code about the available implicit conversion
- inline arithmetic_errc_error make_status_code(arithmetic_errc e)
- {
- return arithmetic_errc_error(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::in_place, e);
- }
- BOOST_OUTCOME_V2_NAMESPACE_BEGIN
- namespace trait
- {
- // Tell Outcome that arithmetic_errc is convertible into std::error
- template <> struct is_error_type_enum<error, arithmetic_errc>
- {
- static constexpr bool value = true;
- };
- }
- BOOST_OUTCOME_V2_NAMESPACE_END
- // And tell Outcome how to perform the implicit conversion
- inline error make_error_code(arithmetic_errc e)
- {
- return arithmetic_errc_error(BOOST_OUTCOME_SYSTEM_ERROR2_NAMESPACE::in_place, e);
- }
- result<int, error> safe_divide(int i, int j)
- {
- if(j == 0)
- {
- return arithmetic_errc::divide_by_zero;
- }
- if(i == INT_MIN && j == -1)
- {
- return arithmetic_errc::integer_divide_overflows;
- }
- if(i % j != 0)
- {
- return arithmetic_errc::not_integer_division;
- }
- return i / j;
- }
- int caller2(int i, int j)
- {
- auto r = safe_divide(i, j);
- if(r)
- {
- return r.value();
- }
- if(r.error() == arithmetic_errc::divide_by_zero)
- {
- return 0;
- }
- if(r.error() == arithmetic_errc::not_integer_division)
- {
- return i / j; // ignore
- }
- if(r.error() == arithmetic_errc::integer_divide_overflows)
- {
- return INT_MIN;
- }
- return 0;
- }
- int main()
- {
- printf("%d\n", caller2(5, 6)); // NOLINT
- return 0;
- }
|