@@ -43,21 +43,34 @@ namespace mgis {
4343 enum FailureHandlerPolicy { ABORT, RAISE };
4444 template <FailureHandlerPolicy policy>
4545 struct FailureHandler {
46- FailureHandler (Context &c) : ctx(c) {}
46+ explicit FailureHandler (Context &c) noexcept : ctx(c) {}
4747 template <typename T>
48- constexpr T &&operator ()(std::optional<T> &&v) const {
48+ decltype (auto ) operator ()(T &&v) const
49+ requires ((internal::OptionalTraits<T>::isSpecialized) &&
50+ (std::is_rvalue_reference_v<decltype (v)>)) {
4951 if (isInvalid (v)) {
50- raise (this ->ctx .getErrorMessage ());
52+ if (policy == FailureHandlerPolicy::RAISE) {
53+ raise (this ->ctx .getErrorMessage ());
54+ } else {
55+ this ->ctx .abort ();
56+ }
5157 }
52- return std::move (*v );
58+ return internal::OptionalTraits<T>:: deference ( std::move (v) );
5359 }
5460 template <typename T>
55- constexpr T &operator ()(OptionalReference<T> &&v) const {
61+ decltype (auto ) operator ()(T &&v) const
62+ requires ((!internal::OptionalTraits<T>::isSpecialized) &&
63+ (std::is_rvalue_reference_v<decltype (v)>)) {
5664 if (isInvalid (v)) {
5765 raise (this ->ctx .getErrorMessage ());
5866 }
59- return *v ;
67+ return std::move (v) ;
6068 }
69+ template <typename T>
70+ friend decltype (auto ) operator|(T &&v, const FailureHandler &h) requires(
71+ std::is_rvalue_reference_v<decltype (v)>) {
72+ return h (std::move (v));
73+ } // end of operator|
6174
6275 private:
6376 // ! \brief reference to the context that created the failure handler
@@ -84,13 +97,19 @@ namespace mgis {
8497 void setVerbosityLevel (const VerbosityLevel) noexcept ;
8598 /* !
8699 * \return a failure handler
87- * \param[in] policy: policy used to treat a failure
100+ * \tparam policy: policy used to treat a failure
88101 * \note the context must outlive the failure hander
89102 */
90103 template <FailureHandlerPolicy policy = FailureHandlerPolicy::RAISE>
91- constexpr FailureHandler<policy> getFailureHandler () {
92- return {*this };
104+ [[nodiscard]] FailureHandler<policy> getFailureHandler () {
105+ return FailureHandler<policy> {*this };
93106 }
107+ // ! \return a failure handler throwing exception in case of failure
108+ [[nodiscard]] FailureHandler<FailureHandlerPolicy::RAISE>
109+ getThrowingFailureHandler () noexcept ;
110+ // ! \return a failure handler aborting the execution in case of failure
111+ [[nodiscard]] FailureHandler<FailureHandlerPolicy::ABORT>
112+ getFatalFailureHandler () noexcept ;
94113 /* !
95114 * \brief set the current log stream.
96115 * \param[in] s: log stream
@@ -162,6 +181,9 @@ namespace mgis {
162181 Context (const Context &) = delete ;
163182 Context &operator =(Context &&) = delete ;
164183 Context &operator =(const Context &) = delete ;
184+ // ! \brief printing the error message on the log stream and abort the
185+ // ! execution
186+ [[noreturn]] void abort ();
165187 // ! \brief current log stream
166188 std::variant<std::monostate, std::ostream *, std::shared_ptr<std::ostream>>
167189 log_stream;
0 commit comments