/* * File: option.hpp * Author: Amlal El Mahrouss, * Copyright 2023-2025, Amlal El Mahrouss, Licensed under the Boost Software License */ #ifndef __OCL_CORE_OPTION #define __OCL_CORE_OPTION #include #include namespace ocl { enum struct return_type { invalid = 0, okay = 100, err, count = err - okay + 1, }; class option final { public: option() = delete; explicit option(const return_type& return_type) : ret_(return_type) { assert(ret_ != return_type::invalid); } ~option() = default; option& operator=(const option&) = delete; option(const option&) = delete; option& expect(const char* input) { assert(ret_ != return_type::invalid); if (ret_ == return_type::err) { throw std::runtime_error(input ? input : "option::error"); } return *this; } template option& expect_or_handle(const char* input) { assert(ret_ != return_type::invalid); if (ret_ == return_type::err) { // AMLALE: Shall it be a functor or container here? ErrorHandler{}(input ? input : "option::error"); } return *this; } private: return_type ret_{return_type::invalid}; }; namespace detail { // AMLALE: They (operator()) were marked `noexcept` as failing conditions within an evaluation (say a overloads operator==) proves that the // predictate is wrong. struct teller { explicit teller() = default; virtual ~teller() = default; template bool operator()(ObjFirst a, ObjLast b) noexcept { return false; } }; struct int_eq_teller final : teller { template bool operator()(ObjFirst a, ObjLast b) noexcept { return (a == b); } }; struct int_greater_than_teller final : teller { template bool operator()(ObjFirst a, ObjLast b) noexcept { return (a > b); } }; struct int_less_than_teller final : teller { template bool operator()(ObjFirst a, ObjLast b) noexcept { return (a < b); } }; } // namespace detail template inline return_type eval(const Teller& tell, Lst&&... arg) { static_assert(std::is_base_of_v, "Teller is not evalueable."); return tell(std::forward(arg)...) ? return_type::okay : return_type::err; } template inline return_type eval_less_than(Lst&&... arg) noexcept { return detail::int_less_than_teller{}(std::forward(arg)...) ? return_type::okay : return_type::err; } template inline return_type eval_eq(Lst&&... arg) noexcept { return detail::int_eq_teller{}(std::forward(arg)...) ? return_type::okay : return_type::err; } template inline return_type eval_greater_than(Lst&&... arg) noexcept { return detail::int_greater_than_teller{}(std::forward(arg)...) ? return_type::okay : return_type::err; } inline return_type eval_true() noexcept { return return_type::okay; } inline return_type eval_false() noexcept { return return_type::err; } inline return_type eval_invalid() noexcept { return return_type::invalid; } } // namespace ocl #endif /* ifndef __OCL_CORE_OPTION */