Overview
The standard library provides predefined enumeration classes to define error conditions for these categories: generic_category, iostream_category and future_categoty.
Details
The following discusses some of the predefined error conditions and error codes. They are organized into a enum class for each category.
In addition, helper classes is_error_condition_enum or is_error_condition_enum are defined to indicate if they are defined for a error_code or error_condition.
The enumerated value is used by helper functions make_error_code() and make_error_condition() to create a error_code or a error_condtion.
is_error_code_enum
This is a traits class to identify whether a particular type is an error code enum type, and thus can be used to construct or assign values to objects of type error_code.
Syntax
template <class T> struct is_error_code_enum : public false_type {};
The standard header only provides the default definition, which simply inherits from false_type. But it should be specialized as inheriting from true_type to enable the construction of error_code object from error code enum types. The standard error condition types io_errc and future_errc inherit true_type.
is_error_condition_enum
This is a traits class to identify whether a particular type is an error condition enum type, and thus can be used to construct or assign values to objects of type error_condition.
Syntax
template <class T> struct is_error_condition_enum : public false_type {};
The standard header only provides the default definition, which simply inherits from false_type. But it should be specialized as inheriting from true_type to enable the construction of error_condition object from error condition enum types. The standard error condition type errc inherit true_type.
make_error_code()
Syntax
make_error_code(econd_enum e)
Creates an error_code for econd_enum e and returns it.
It's equivalent to error_code(static_cast<int>(e), cat) where cat is the category for which econd_enumaration enum is defined.
make_error_condition()
Syntax
make_error_condition(econd_enum e)
Creates an error_condition for econd_enumaration enum e and returns it.
It's equivalent to error_condition(static_cast<int>(e), cat) where cat is the category for which econd_enumaration enum is defined.
used to construct or assign values to objects of type error_code.
errc
enum class with enumerators for the error_conditions with one to one mapping to error codes from POSIX error codes which are found in <cerrno> header file.
Type trait class is_error_condition_enum is implemented returning true, indicating that it's an error_condition enumeration.
Helper functions make_error_code() and make_error_condition() are also implemented.
error_condition ecnd = make_error_condition(errc::invalid_argument); //same as //error_condition ecnd = make_error_condition(EINVAL, std::generic_category());
The complete list can be viewed here.
void print_error(const std::string& details, std::error_code error_code) { std::string value_name; if (error_code == std::errc::invalid_argument) value_name = "std::errc::invalid_argument"; if (error_code == std::errc::no_such_file_or_directory) value_name = "std::errc::no_such_file_or_directory"; if (error_code == std::errc::is_a_directory) value_name = "std::errc::is_a_directory"; if (error_code == std::errc::permission_denied) value_name = "std::errc::permission_denied"; std::cerr << details << ":\n " << std::quoted(error_code.message()) << " (" << value_name << ")\n\n"; } void print_errno(const std::string& details, int errno_value = errno) { print_error(details, std::make_error_code(std::errc(errno_value))); } int main() { /*prints Detaching a not-a-thread... Error detaching empty thread: "Invalid argument" (std::errc::invalid_argument) */ std::cout << "Detaching a not-a-thread...\n"; try { std::thread().detach(); } catch (const std::system_error& e) { print_error("Error detaching empty thread", e.code()); } /*prints Opening nonexistent file... Error opening nonexistent file for reading: "No such file or directory" (std::errc::no_such_file_or_directory) */ std::cout << "Opening nonexistent file...\n"; std::ifstream nofile{"nonexistent-file"}; if (!nofile.is_open()) print_errno("Error opening nonexistent file for reading"); /*prints Reading from directory as a file... Error reading data from directory: "Is a directory" (std::errc::is_a_directory) */ std::cout << "Reading from directory as a file...\n"; std::filesystem::create_directory("dir"); std::ifstream dir_stream{"dir"}; [[maybe_unused]] char c = dir_stream.get(); if (!dir_stream.good()) print_errno("Error reading data from directory"); /*prints Open read-only file for writing... Error opening read-only file for writing: "Permission denied" (std::errc::permission_denied) */ std::cout << "Open read-only file for writing...\n"; std::fstream{"readonly-file", std::ios::out}; std::filesystem::permissions("readonly-file", std::filesystem::perms::owner_read); std::fstream write_readonly("readonly-file", std::ios::out); if (!write_readonly.is_open()) print_errno("Error opening read-only file for writing");
future_errc
enum class with enumerators for error_codes for future errors.
Type trait class is_error_code_enum is implemented returning true, indicating that it's an error_code enumeration.
Helper functions make_error_code() and make_error_condition() are also implemented.
error_condition ecnd = make_error_condition(future_errc::future_already_retrieved); //same as //error_condition ecnd = make_error_condition(1, std::future_category());
The complete list can be viewed here.
std::promise<int> prom; //prints:[future already retrieved] try { prom.get_future(); prom.get_future(); // throws std::future_error with future_already_retrieved } catch (std::future_error& e) { if (e.code() == std::make_error_condition(std::future_errc::future_already_retrieved)) std::cerr << "[future already retrieved]\n"; else std::cerr << "[unknown exception]\n"; }
io_errc
enum class with enumerators for io stream errors.
Type trait class is_error_code_enum is implemented returning true, indicating that it's an error_code enumeration.
Helper functions make_error_code() and make_error_condition() are also implemented.
error_condition ecnd = make_error_condition(io_errc::stream); //same as //error_condition ecnd = make_error_condition(1, std::iostream_category());
The complete list can be viewed here.
//prints:failure caught: stream error condition try { std::cin.rdbuf(nullptr); // throws std::cin.exceptions (std::ios::failbit|std::ios::badbit); } catch (std::ios::failure& e) { std::cerr << "failure caught: "; if ( e.code() == std::make_error_condition(std::io_errc::stream) ) std::cerr << "stream error condition\n"; else std::cerr << "some other error condition\n"; }
No comments:
Post a Comment