Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

An exceptionless version that does not throw? #134

Open
siradam7th opened this issue Sep 29, 2020 · 3 comments
Open

An exceptionless version that does not throw? #134

siradam7th opened this issue Sep 29, 2020 · 3 comments

Comments

@siradam7th
Copy link

Is there any interest in having a version of the library that does not throw exceptions everywhere?
If yes, how would the API for such thing look like?

Example: this will add an extra parameter at the end of function definitions which could be default initialized so it does not require changes to existing code:

TomlError error = {}; 
auto v = toml::parse(file_path, error);

and TomlError is defined such that:

enum class TomlErrorType
{
   FILE_NOT_OPEN // toml::parse: file open error
   // the rest of the errors
};

struct TomlError
{
    TomlErrorType type;
    std::string msg; // or const char*
};

Looking forward for your opinion on this.

@siradam7th
Copy link
Author

I came up with another solution that does not change the library as much, here is how it works:

When a macro TOML_NO_EXCEPTIONS is defined, the regular toml::exception does not inherit from std::exception, and the rest of the exception types will inherit from a virtual class that provides the same virtual functions so that everything just works.

syntax_error, type_error, internal_error

For places that throw exceptions, if the macro is defined, the functions will have an extra parameter at the end that returns the exception object instead of it being thrown, the rest of the code is the same.
The exception object will contain the same information, plus it will have a boolean operator so that the returned object can be checked to see if the function succeeded or not just like shown in the previous example.

toml::toml_error error;
auto v = toml::parse(file_path, error);
if(!error)
{
    // call failed
}

@ToruNiina
Copy link
Owner

I have been interested in this topic. My plan is to use toml::result type that is already used internally. The main reason why I defined and introduced toml::result is this. But since I need to refactor several part a bit to avoid some difficulty in error message generation, so I have not done it yet. In the next major release (v4), I want to support that with some other changes like customizable formatter.

In my plan, the interface would look like the following. I want to have some space to extend it more later, having toml::option or parse_option could be useful. By templatizing it, we can change the return type through it.

toml::parse(std::string filename, toml::option<...> opt = toml::option<>{});

Main concern is compilation speed and backward compatibility. I will try to reduce compilation overhead and to minimize the difference from the current version, but it is a hard task. Firstly, I need to find a solid blocks of time to focus on it.

(Strictly speaking, making toml::parse noexcept is very challenging. Since even new can throw bad_alloc, an exception might be thrown from almost everywhere. But I think we are discussing about exceptions caused by a syntax error. Is it correct?)

@siradam7th
Copy link
Author

siradam7th commented Nov 27, 2020

Since even new can throw bad_alloc

there is a version of new that does not throw and instead returns nullptr on failure, https://en.cppreference.com/w/cpp/memory/new/nothrow

And yes, i'm talking about exceptions that are caused by syntax errors.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants