Open Search
    resultbase.h File Reference

    Classes

    struct  ResultOkError
     
    struct  TmpErrType< T >
     
    struct  TmpErrType< ResultOk< T > >
     
    class  ResultOk< T >
     
    class  ResultOk< T & >
     
    class  ResultOk< void >
     
    class  ResultMemT< T >
     
    struct  ForwardResultPtr< T >
     
    class  ResultRef< T >
     
    class  ResultBase< T >
     
    class  ResultBase< T & >
     
    class  ResultBase< void >
     
    class  PrivateIsErrorClassHelper< T, IS_OBJECT_REF >
     
    class  PrivateIsErrorClassHelper< T, true >
     
    class  IsErrorClass< T >
     
    class  IsErrorClass< ForwardRef< T > >
     
    class  ResultSuper< RESULT_TYPE, ENABLE >
     
    class  ResultSuper< RESULT_TYPE, typename SFINAEHelper< void, typename RESULT_TYPE::template ResultFunctions< ResultBase< RESULT_TYPE > > >::type >
     
    class  ResultSuper< RESULT_TYPE &, typename SFINAEHelper< void, typename RESULT_TYPE::template ResultFunctions< ResultBase< RESULT_TYPE & > > >::type >
     
    class  Result< RESULT_TYPE >
     
    struct  RemoveResult< T >
     
    struct  RemoveResult< Result< T > >
     
    struct  RemoveResult< ResultOk< T > >
     
    struct  GenericCastMemberTrait< Result< TO >, Result< FROM >, SAFE >
     
    struct  GenericCastTrait< Result< TO >, FROM, SAFE >
     
    struct  GenericCastTrait< Result< TO >, Result< FROM >, SAFE >
     
    class  ResultIteratorFunctions< SUPER >
     
    class  ResultIteratorFunctions< SUPER >::Wrapper
     

    Namespaces

     maxon
     
     maxon::details
     

    Macros

    #define PRIVATE_MAXON_RBF_SENTINEL(...)
     
    #define PRIVATE_MAXON_ENABLE_IF_ERROR(TYPE)
     
    #define PRIVATE_MAXON_ENABLE_IF_ERROR_DUMMY
     
    #define PRIVATE_MAXON_iferr_scope(T)
     
    #define PRIVATE_MAXON_iferr_scope_handler()
     
    #define PRIVATE_MAXON_iferr_diag_handler0(errResult, formatString, ...)
     
    #define PRIVATE_MAXON_iferr_diag_handler1(errResult, formatString, ...)
     
    #define PRIVATE_MAXON_iferr_diag_handlerc(vaArgsPopulated, errResult, formatString, ...)
     
    #define PRIVATE_MAXON_iferr_diag_handlerb(vaArgsPopulated, errResult, formatString, ...)
     
    #define PRIVATE_MAXON_iferr_diag_handlera(vaArgsPopulated, errResult, formatString, ...)
     
    #define PRIVATE_MAXON_iferr_return()
     
    #define PRIVATE_MAXON_iferr_cannot_fail(str)
     
    #define PRIVATE_MAXON_iferr_ignore_method(str, optionalArg, method, ...)
     
    #define PRIVATE_MAXON_iferr_ignore(...)
     
    #define iferr_scope
     
    #define iferr_scope_handler
     
    #define iferr_diag_handler(errResult, formatString, ...)
     
    #define iferr_cannot_fail(str)
     
    #define iferr_ignore(...)
     
    #define iferr_scope_result
     
    #define iferr_return
     
    #define PRIVATE_iferr_throw(VAR, ...)
     
    #define iferr_throw(ERR)
     

    Typedefs

    template<typename T >
    using ResultPtr = ResultMemT< T * >
     

    Enumerations

    enum class  ERROR_OK { VALUE }
     
    enum class  ERROR_FAILED { VALUE }
     
    enum class  ERROR_TYPE {
      OUT_OF_MEMORY ,
      NULLPTR ,
      ILLEGAL_ARGUMENT ,
      ILLEGAL_STATE ,
      NOT_IMPLEMENTED ,
      UNRESOLVED ,
      UNKNOWN
    }
     

    Functions

    enum maxon::ERROR_OK MAXON_ENUM_LIST (ERROR_OK)
     
    enum maxon::ERROR_FAILED MAXON_ENUM_LIST (ERROR_FAILED)
     
    enum maxon::ERROR_TYPE MAXON_ENUM_LIST (ERROR_TYPE)
     
    const Error * CreateErrorPtr (MAXON_SOURCE_LOCATION_DECLARATION, ERROR_TYPE type) __attribute__((pure
     
    ThreadReferencedError CreateError (MAXON_SOURCE_LOCATION_DECLARATION, ERROR_TYPE type)
     
    const Error * PrivateSystemSetCurrentError (const Error &error)
     
    const Error * PrivateSystemSetCurrentError (Error &&error)
     
    void PrivateSetError (Error &dest, const Error *src)
     
     MAXON_MEMBERTYPE_DETECTOR (IsForwardRef, IsForwardRef, std::false_type)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE auto operator% (const ResultOk< T > &rv, ThreadReferencedError &err) -> decltype(rv.GetValue())
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINEoperator% (ResultOk< T > &&rv, ThreadReferencedError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE T & operator% (ResultOk< T & > &&rv, ThreadReferencedError &err)
     
    MAXON_ATTRIBUTE_FORCE_INLINE void operator% (ResultOk< void > &&rv, ThreadReferencedError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE auto operator% (const ResultOk< T > &rv, maxon::details::ResultOkError &err) -> decltype(rv.GetValue())
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINEoperator% (ResultOk< T > &&rv, maxon::details::ResultOkError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE T & operator% (ResultOk< T & > &&rv, maxon::details::ResultOkError &err)
     
    MAXON_ATTRIBUTE_FORCE_INLINE void operator% (ResultOk< void > &&rv, maxon::details::ResultOkError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE auto operator% (const Result< T > &rv, ThreadReferencedError &err) -> decltype(rv.GetValue())
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINEoperator% (Result< T > &&rv, ThreadReferencedError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE T & operator% (const Result< T & > &rv, ThreadReferencedError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE T & operator% (Result< T & > &&rv, ThreadReferencedError &err)
     
    MAXON_ATTRIBUTE_FORCE_INLINE void operator% (const Result< void > &rv, ThreadReferencedError &err)
     
    MAXON_ATTRIBUTE_FORCE_INLINE void operator% (Result< void > &&rv, ThreadReferencedError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE T && operator% (ResultMemT< T > &&ptr, ThreadReferencedError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE const T & operator% (const ResultMemT< T > &ptr, ThreadReferencedError &err)
     
    template<typename T >
    MAXON_ATTRIBUTE_FORCE_INLINE T & operator% (ResultRef< T > ptr, ThreadReferencedError &err)
     

    Variables

     VALUE
     
    static const ERROR_FAILED FAILED
     
     OUT_OF_MEMORY
     
     NULLPTR
     
     ILLEGAL_ARGUMENT
     
     ILLEGAL_STATE
     
     NOT_IMPLEMENTED
     
     UNRESOLVED
     
     UNKNOWN
     
    const Error returns_nonnull
     

    Macro Definition Documentation

    ◆ PRIVATE_MAXON_RBF_SENTINEL

    #define PRIVATE_MAXON_RBF_SENTINEL (   ...)

    ◆ PRIVATE_MAXON_ENABLE_IF_ERROR

    #define PRIVATE_MAXON_ENABLE_IF_ERROR (   TYPE)

    ◆ PRIVATE_MAXON_ENABLE_IF_ERROR_DUMMY

    #define PRIVATE_MAXON_ENABLE_IF_ERROR_DUMMY

    ◆ PRIVATE_MAXON_iferr_scope

    #define PRIVATE_MAXON_iferr_scope (   T)

    ◆ PRIVATE_MAXON_iferr_scope_handler

    #define PRIVATE_MAXON_iferr_scope_handler ( )

    ◆ PRIVATE_MAXON_iferr_diag_handler0

    #define PRIVATE_MAXON_iferr_diag_handler0 (   errResult,
      formatString,
      ... 
    )

    ◆ PRIVATE_MAXON_iferr_diag_handler1

    #define PRIVATE_MAXON_iferr_diag_handler1 (   errResult,
      formatString,
      ... 
    )

    ◆ PRIVATE_MAXON_iferr_diag_handlerc

    #define PRIVATE_MAXON_iferr_diag_handlerc (   vaArgsPopulated,
      errResult,
      formatString,
      ... 
    )

    ◆ PRIVATE_MAXON_iferr_diag_handlerb

    #define PRIVATE_MAXON_iferr_diag_handlerb (   vaArgsPopulated,
      errResult,
      formatString,
      ... 
    )

    ◆ PRIVATE_MAXON_iferr_diag_handlera

    #define PRIVATE_MAXON_iferr_diag_handlera (   vaArgsPopulated,
      errResult,
      formatString,
      ... 
    )

    ◆ PRIVATE_MAXON_iferr_return

    #define PRIVATE_MAXON_iferr_return ( )

    ◆ PRIVATE_MAXON_iferr_cannot_fail

    #define PRIVATE_MAXON_iferr_cannot_fail (   str)

    ◆ PRIVATE_MAXON_iferr_ignore_method

    #define PRIVATE_MAXON_iferr_ignore_method (   str,
      optionalArg,
      method,
      ... 
    )

    ◆ PRIVATE_MAXON_iferr_ignore

    #define PRIVATE_MAXON_iferr_ignore (   ...)

    ◆ iferr_scope

    #define iferr_scope

    Instead of using iferr you can define an iferr_scope and within this scope call methods which might return an error (and decorate them with the iferr_return attribute). If a method returns with an error iferr_return will forward it.

    FuncA() iferr_return;
    FuncB() iferr_return;
    #define iferr_scope
    Definition: resultbase.h:1389
    #define iferr_return
    Definition: resultbase.h:1524

    ◆ iferr_scope_handler

    #define iferr_scope_handler

    To perform a specific action in case of an error (additional logging, or just to set a breakpoint for debugging) you can replace iferr_scope by an iferr_scope_handler:

    {
    DebugStop("special message");
    return err;
    };
    FuncA() iferr_return;
    FuncB() iferr_return;
    #define DebugStop(...)
    Definition: debugdiagnostics.h:225
    #define iferr_scope_handler
    Definition: resultbase.h:1407

    iferr_scope_handler implicitely defines the error variable 'err'.

    ◆ iferr_diag_handler

    #define iferr_diag_handler (   errResult,
      formatString,
      ... 
    )

    Condensed version of iferr_scope_handler. Allows to add some local context to error coming from inner calls (lower level code). The nested error and local context are printed to the console based on g_diagnostic configuration. Can be used on legacy code side of Maxon API code side since the handler's return value is defined by the first argument #errResult. See iferr_scope for details. One per scope only.

    auto SomeFuncA()
    {
    iferr_diag_handler(localVariable, "Error occurred: CSV data invalid file(@)"_s, filePath);
    ...
    }
    Int SomeFuncB()
    {
    iferr_diag_handler(Int{-1}, "Invalid node argument. Value=@ Attrib=@"_s, attribValue, attribId);
    ...
    }
    Result<void> SomeFuncC()
    {
    iferr_diag_handler(OK, "Function Name: context(@)"_s, ctx);
    ...
    }
    Result<Array<Int>> SomeFuncD()
    {
    iferr_diag_handler(err, "My simple context"_s);
    ...
    }
    void SomeFuncE()
    {
    iferr_diag_handler(, "Function E with no return value."_s);
    ...
    }
    OK
    User has selected a font.
    Definition: customgui_fontchooser.h:0
    maxon::Int Int
    Definition: ge_sys_math.h:60
    #define iferr_diag_handler(errResult, formatString,...)
    Definition: resultbase.h:1451
    Parameters
    [in]errResultValue to return in case of error.
    [in]formatStringFormat for the DiagnosticOutput embedded call. Variadic arguments should match the number of '@' in #formatString. err.ToString() will be added automatically at the end of the string.
    Returns
    #errResult. Can be "err" or maxon::OK if function return type is Result<T>. Or any default value or variable which has a compatible type.

    ◆ iferr_cannot_fail

    #define iferr_cannot_fail (   str)

    If an error cannot occur (because you've ensured this by preallocating resources or the algorithm was designed in such a way, etc.) you might use iferr_cannot_fail with a comment which explans why it can't fail. In debug this will check for errors and invoke DebugStop() to notify you that your code is broken, but in release there are no error checks.

    BaseArray<Int> array;
    array.EnsureCapacity(42) iferr_return;
    for (Int i = 0; i < GetCapacityCount(); i++)
    array.Append(i) iferr_cannot_fail("Capacity was ensured.");
    Py_ssize_t i
    Definition: abstract.h:645
    #define iferr_cannot_fail(str)
    Definition: resultbase.h:1468

    ◆ iferr_ignore

    #define iferr_ignore (   ...)

    If for perfomance reasons a piece of code has been very carefully designed in a way that error checking is performed at the very end and that no checks are necessary inbetween you may qualify calls with iferr_ignore and a comment which describes why the error can be ignored.

    Note
    This should only be used for performance critical code which has been profiled properly and has been reviewed thoroughly.
    You might supply an optional second parameter (debug) to cause a DebugStop on error.
    BaseArray<Int> array;
    const Int CNT = 42;
    for (Int i = 0; i < CNT; i++)
    array.Append(i) iferr_ignore("Errors are handled after append");
    if (array.GetCount() != CNT)
    return OutOfMemoryError(MAXON_SOURCE_LOCATION);
    #define MAXON_SOURCE_LOCATION
    Definition: memoryallocationbase.h:67
    #define iferr_ignore(...)
    Definition: resultbase.h:1489

    ◆ iferr_scope_result

    #define iferr_scope_result

    Use iferr_scope_result in finally blocks to deallocate resources based on the error state.

    finally
    {
    destructSecond = true;
    };
    FAILED
    Generic error if a rendering has failed due to missing license or similar.
    Definition: ge_prepass.h:8
    #define iferr_scope_result
    Definition: resultbase.h:1501

    ◆ iferr_return

    #define iferr_return

    The iferr_return macro is the easiest way to introduce error handling. It quickly allows you leave a function as soon as an error occurs. iferr_return requires you to define iferr_scope or iferr_scope_handler once beforehand (preferably at the beginning of your function)

    ...
    for (Int i = 0; i < 5; i++)
    {
    array.Append(5) iferr_return;
    }
    MyRef ref = MyRef::Create() iferr_return;
    PyObject * obj
    Definition: complexobject.h:60
    static auto Create(ARGS &&... args)
    Definition: apibase.h:2818

    iferr_return forwards the error to the calling function. To do this your function must either return Result<T> or use an iferr_scope_handler.
    When iferr_return is used within 'for', 'if', 'else' or 'while' those statements must use brackets around their scope, otherwise iferr_return will not be properly executed.

    ◆ PRIVATE_iferr_throw

    #define PRIVATE_iferr_throw (   VAR,
      ... 
    )

    ◆ iferr_throw

    #define iferr_throw (   ERR)

    Manually throw an error. Especially useful in combination with iferr_scope_handler to cleanup things in case of errors. Usually you just create error messages and return them in case of a problem like in this example:

    static Result<void> DoSomething()
    {
    Char* mem = NewMem(Char, 200) iferr_return;
    while (true)
    {
    // do something
    ...
    if (FuncA() != 2)
    return IllegalStateError(MAXON_SOURCE_LOCATION, "Invalid return value"_s);
    ...
    if (FuncB() != 40)
    return IllegalStateError(MAXON_SOURCE_LOCATION, "Invalid return value"_s);
    ...
    if (FuncC() != -3)
    return IllegalStateError(MAXON_SOURCE_LOCATION, "Invalid return value"_s);
    }
    DeleteMem(mem);
    return OK;
    }
    #define NewMem(T, cnt)
    Definition: defaultallocator.h:195
    maxon::Char Char
    Definition: ge_sys_math.h:52
    void DeleteMem(T *&p)
    Definition: defaultallocator.h:257

    The big problem is that in case of an error the allocated chars are nevers freed. Instead of deleting the mem at each possible error point in the algo you can throw the error instead of returning them and then catch the error with iferr_scope_handler and handle the cleanup at a single place like in this example:

    static Result<void> DoSomething()
    {
    Char* mem = nullptr;
    {
    DeleteMem(mem); // always guarantee cleanup even in error case
    return err;
    };
    mem = NewMem(Char, 200) iferr_return;
    while (true)
    {
    // do something
    ...
    if (FuncA() != 2)
    iferr_throw(IllegalStateError(MAXON_SOURCE_LOCATION, "Invalid return value"_s));
    ...
    if (FuncB() != 40)
    iferr_throw(IllegalStateError(MAXON_SOURCE_LOCATION, "Invalid return value"_s));
    ...
    if (FuncC() != -3)
    iferr_throw(IllegalStateError(MAXON_SOURCE_LOCATION, "Invalid return value"_s));
    }
    DeleteMem(mem);
    return OK;
    }
    #define iferr_throw(ERR)
    Definition: resultbase.h:1589

    Variable Documentation

    ◆ VALUE

    VALUE

    The single value of this enum.

    ◆ OUT_OF_MEMORY

    OUT_OF_MEMORY

    Create an OutOfMemoryError.

    ◆ NULLPTR

    NULLPTR

    Create a NullptrError.

    ◆ ILLEGAL_ARGUMENT

    ILLEGAL_ARGUMENT

    Create an IllegalArgumentError.

    ◆ ILLEGAL_STATE

    ILLEGAL_STATE

    Create an IllegalStateError.

    ◆ NOT_IMPLEMENTED

    NOT_IMPLEMENTED

    Create a FunctionNotImplementedError.

    ◆ UNRESOLVED

    UNRESOLVED

    Create an UnresolvedError.

    ◆ UNKNOWN

    UNKNOWN

    < Create an UnknownError.