completed the system_error description in advancedtemplates

This commit is contained in:
Frank B. Brokken 2017-12-02 13:43:03 +01:00
parent 8b41d305a2
commit 0a5dc51fc2
76 changed files with 213 additions and 189 deletions

View file

@ -15,7 +15,7 @@ associations are collected in a class template tt(CatMap), derived from
tt(std::unordered_map). tt(CatMap)'s design is a rather straightforward, tt(std::unordered_map). tt(CatMap)'s design is a rather straightforward,
offering a constructor accepting an tt(std::initializer_list): offering a constructor accepting an tt(std::initializer_list):
verbinsert(-s4 //impl examples/errcode2/catmap/catmap.h) verbinsert(-s4 //impl examples/errcode/catmap/catmap.h)
As tt(ErrorCodeEnum)-values may have been randomly assigned (not using 0) As tt(ErrorCodeEnum)-values may have been randomly assigned (not using 0)
tt(CapMap) objects offers fast access to the errors' descriptions and tt(CapMap) objects offers fast access to the errors' descriptions and
@ -40,7 +40,7 @@ const) member, returning the description matching tt(ev) or the error message
tt(noEnumValue) if tt(ev) does not represent a defined enum value. Here is its tt(noEnumValue) if tt(ev) does not represent a defined enum value. Here is its
implementation: implementation:
verbinsert(-s4 //msg examples/errcode2/categorybase/categorybase.h) verbinsert(-s4 //msg examples/errcode/categorybase/categorybase.h)
But that isn't all that tt(CategoryBase) can accomplish: since it contains But that isn't all that tt(CategoryBase) can accomplish: since it contains
tt(s_errors), the associations between error enum values and category tt(s_errors), the associations between error enum values and category
@ -59,7 +59,7 @@ tt(s_errors), and compares the stored error condition's name to the name
provided by the (singleton) tt(error_condition) object, given the condition's provided by the (singleton) tt(error_condition) object, given the condition's
number. Here is its implementation: number. Here is its implementation:
verbinsert(-s4 //equiv examples/errcode2/categorybase/categorybase.h) verbinsert(-s4 //equiv examples/errcode/categorybase/categorybase.h)
In addition, to allow single inheritance to be used when deriving classes from In addition, to allow single inheritance to be used when deriving classes from
tt(std::error_category) the class tt(CategoryBase) itself is derived from tt(std::error_category) the class tt(CategoryBase) itself is derived from
@ -71,7 +71,7 @@ tt(equivalent) that can be used by all classes derived from
tt(std::error_category); and, finally, a class that itself also is an tt(std::error_category); and, finally, a class that itself also is an
tt(error_category) class. Here is the interface of tt(CategoryBase): tt(error_category) class. Here is the interface of tt(CategoryBase):
verbinsert(-s4 //impl examples/errcode2/categorybase/categorybase.h) verbinsert(-s4 //impl examples/errcode/categorybase/categorybase.h)
Now we're ready for defining our own error category classes. To define a Now we're ready for defining our own error category classes. To define a
category class we take the following steps: category class we take the following steps:
@ -86,12 +86,12 @@ category class we take the following steps:
tt(CalculatorCategory's) class interface: tt(CalculatorCategory's) class interface:
verbinsert(//class verbinsert(//class
examples/errcode2/calculatorcategory/calculatorcategory.h) examples/errcode/calculatorcategory/calculatorcategory.h)
The member tt(instance) returns a reference to the singleton object, The member tt(instance) returns a reference to the singleton object,
initializing it the first time it is called: initializing it the first time it is called:
verbinsert(//impl examples/errcode2/calculatorcategory/instance.cc) verbinsert(//impl examples/errcode/calculatorcategory/instance.cc)
it() The member tt(name) simply returns a short string naming the category it() The member tt(name) simply returns a short string naming the category
(tt("calculator") for the calculator category). (tt("calculator") for the calculator category).
@ -100,7 +100,7 @@ category class we take the following steps:
thanks to tt(CategoryBase::member): it merely returns what's returned by thanks to tt(CategoryBase::member): it merely returns what's returned by
that latter member: that latter member:
verbinsert(//impl examples/errcode2/calculatorcategory/messace.cc) verbinsert(//impl examples/errcode/calculatorcategory/messace.cc)
it() The associations between error code enum values, descriptions and it() The associations between error code enum values, descriptions and
error condition names are defined when initializing the tt(CatMap) error condition names are defined when initializing the tt(CatMap)
@ -108,20 +108,20 @@ category class we take the following steps:
base class it can be initialized when defining the category base class it can be initialized when defining the category
class. Here is the initialization for tt(CalculatorCategory): class. Here is the initialization for tt(CalculatorCategory):
verbinsert(//impl examples/errcode2/calculatorcategory/data.cc) verbinsert(//impl examples/errcode/calculatorcategory/data.cc)
it() We're now in position to actually create tt(error_code) objects from it() We're now in position to actually create tt(error_code) objects from
tt(CalculatorError) enum values. For this we define the free function tt(CalculatorError) enum values. For this we define the free function
tt(make_error_code(CalculatorError ce)): tt(make_error_code(CalculatorError ce)):
verbinsert(//impl examples/errcode2/calculatorcategory/makeerrorcode.cc) verbinsert(//impl examples/errcode/calculatorcategory/makeerrorcode.cc)
) )
Now that a tt(CalculatorError) value can be converted to an Now that a tt(CalculatorError) value can be converted to an
tt(std::error_code) we can use it in our programs. Here is a little demo tt(std::error_code) we can use it in our programs. Here is a little demo
program illustrating its use: program illustrating its use:
verbinsert(-as4 examples/errcode2/main.part); verbinsert(-as4 examples/errcode/main.part);
In the next section defining and using error conditions is covered in detail. In the next section defining and using error conditions is covered in detail.

View file

@ -44,8 +44,8 @@ itemization(
it() Our first step consists of defining our own error enumerations: one it() Our first step consists of defining our own error enumerations: one
related to the calculator and one related to the simulator: related to the calculator and one related to the simulator:
verbinsert(//enum examples/errcode2/calculatorerror/calculatorerror.h) verbinsert(//enum examples/errcode/calculatorerror/calculatorerror.h)
verbinsert(//enum examples/errcode2/simulatorerror/simulatorerror.h) verbinsert(//enum examples/errcode/simulatorerror/simulatorerror.h)
The class tt(std::error_code) is designed so that two pieces of The class tt(std::error_code) is designed so that two pieces of
information (the error value and its category) become available. The information (the error value and its category) become available. The
@ -80,7 +80,7 @@ it() Second, our intention is to let tt(error_code) accept
Here is the specialization for tt(CalculatorError); the one for Here is the specialization for tt(CalculatorError); the one for
tt(SimulatorError) is defined analogously: tt(SimulatorError) is defined analogously:
verbinsert(//trait examples/errcode2/calculatorerror/.h) verbinsert(//trait examples/errcode/calculatorerror/.h)
This completes the definition of our own error enumerations, which are This completes the definition of our own error enumerations, which are
now `promoted' to tt(ErrorCodeEnums). now `promoted' to tt(ErrorCodeEnums).

View file

@ -32,58 +32,68 @@ instead use verbal labels denoting error conditions. So rather than specifying
}; };
) )
textual labels like tt("InputCond", "UnavailCond",) and tt("SystemCond") textual labels like tt("InputCond", "UnavailCond",) and tt("SystemCond")
could be used. Instead of defining a fixed-size tt(enum class ErrorCondition) could be used. Instead of defining a fixed-size tt(ErrorConditionEnum) a
a singleton tt(class ErrorCondition) is defined, guaranteeing the uniqueness singleton class tt(ErrorCondition) is used, providing and encapsulating such
of error conditions which are identified by their textual labels. an enumeration, at the same time guaranteeing the uniqueness of error
conditions which are identified by textual labels.
Error conditions are obtained from a function tt(make_error_condition), The class tt(ConditionCategory) implements the requirements imposed by the
expecting an tt(ErrorConditionEnum) value as its argument, and using an class tt(std::error_condition), tailored to the error conditions managed by
tt(std::error_category) that is associated with the class tt(ErrorCondition). Also designed as a singleton,
the various error condition enum values, much like tt(CalculatorCategory) was tt(ConditionCategory) contains a vector whose elements hold names and
associated with the tt(CalculatorError) enumeration. The tt(std::error_category) descriptions of the various error conditions. In addition to the familiar
members tt(name, message) and tt(equivalent) it offers a member
tt(addCondition). That latter function is used by tt(ErrorCondition) to add
new error conditions to the current set. Here is its interface:
verbinsert(-s4 //class
examples/errcode/conditioncategory/conditioncategory.h)
========================== WIP The members tt(name) and tt(message) have trivial implementations. The member
tt(equivalent) receives an tt(error_code) object and an error condition enum
value (as an tt(int)). The function must return tt(true) if the provided
tt(error_code) is associated with the provided error condition enum
value. tt(Equivalent) itself doesn't perform those checks. Rather, it
retrieves the tt(error_code's error_category) and uses that object's
tt(equivalent) function to perform the test:
verbinsert(-s4 //impl
examples/errcode/conditioncategory/equivalent.cc)
Next we look at the class tt(ErrorCondition). It contains a
tt(ConditionCategory) object (i.e., em(the) tt(ConditionCategory) object), and
a tt(unsorted_map), mapping condition names to their indices in the
tt(ConditionCategory's) vector. Other than that it's a rather plain class,
offering members to retrieve the enum values of the various error conditions,
and returning conditions' names given their numbers. Error condition enum
values are simply defined as their indices in the tt(ConditionCategory's)
vector, statically cast to the enum tt(ErrorCondition::Enum).
tt(Enum) by itself is defined as mere enumeration name, promoted to an
tt(ErrorConditionEnum) by the tt(std::is_error_condition_enum) trait class
specialization (comparable to what the tt(is_error_code_enum) trait class
accomplished for our enums like tt(CalculatorError)). Here is the
tt(is_error_condition_enum) trait class specialization, followed by
tt(ErrorCondition's) class interface:
verbinsert(-s4 //trait examples/errcode/errorcondition/errorcondition.h)
is provided by an object of the class tt(ErrorCondCat) verbinsert(-s4 //class examples/errcode/errorcondition/errorcondition.h)
. To create an tt(error_condition) an tt(ErrorCondition::Enum) value
is required and the enum's value matching error category.
Error conditions objects themselves are returned by a function
tt(make_error_condition), expecting an tt(ErrorConditionEnum) value as its
argument, and internally using an tt(std::error_category) that is associated
with the various error condition enum values, much like tt(CalculatorCategory)
was associated with the tt(CalculatorError) enumeration. Since
tt(ConditionCategory) is a singleton, it can directly pass that singleton
object to the tt(std::error_condition) object:
verbinsert(-s4 //make
examples/errcode/errorcondition/makeerrorcondition.cc)
A demo program illustrating some of the facilities of the tt(error_code,
error_category, error_condition) and related classes concludes this
section. The complete implementation of the program is provided in the
annotations()' source archive in the directory
tt(yo/advancedtemplates/examples/errocde).
: their uniqueness can be guaranteed by another class, verbinsert(-s4 //demo examples/errcode/errcode/main.cc)
tt(ErrorCondition), which is also a singleton. That class defines an empty
tt(enum Enum), which is promoted to an tt(ErrorConditionEnum) by the
tt(std::is_error_condition_enum) trait class specialization:
verbinsert(-s4 //trait examples/errorcondition/errorcondition.h)
Error ondition objects are created by
The tt(ErrorCondition) singleton also has a member tt(addCondition)
allowing programs to add error conditions by name (and a description).
To access error condition objects a
Let's
define our conditions as:
verbinsert(-s4 //simerrsrc examples/errcodeenum.cc)
This allows us to distinguish errors made by the user, errors from the
calculator, and errors from the simulator. As in the previous section, we'll
`promote' this enum, this time to an ti(ErrorConditionEnum):
verbinsert(-s4 //simcondtrait examples/errcodeenum.cc)
Now that an error condition enumeration has been defined, error codes can be
mapped to their appropriate error condition values. To do that, a tt(class
ErrorSourceCategory) is derived (again: in the anonymous namespace) from
tt(std::error_category), similarly to what we did before with, e.g.,
tt(CalculatorErrCategory):
verbinsert(-s4 //errorourcecat examples/errcodeenum.cc)
The tt(name) and tt(message) members are defined as before, but in
addition the member tt(equivalent) is defined comparing a received
tt(error_code) to the available tt(SimErrSource) values. The function
tt(equivalent) returns tt(true) if tt(error_code code) can be mapped to tt(int
condition), which in fact is a statically cast tt(SimErrSource) value. For tt(

View file

@ -0,0 +1,3 @@
calculatorerror
simulatorerror
errorsource

View file

@ -3,7 +3,7 @@
#include <system_error> #include <system_error>
//enum //calcerrc
enum class CalculatorError enum class CalculatorError
{ {
// no 0, since that's by convention implies no error // no 0, since that's by convention implies no error
@ -16,19 +16,25 @@ enum class CalculatorError
MissingParentheses, // ( and ) don't match MissingParentheses, // ( and ) don't match
}; };
//= //=
//trait
class CalculatorCategory: public std::error_category
{
char const *name() const noexcept override;
std::string message(int ce) const override;
};
extern CalculatorCategory const calculatorCategory;
std::error_code make_error_code(CalculatorError ce);
//calctrait
namespace std namespace std
{ {
template <> template <>
struct is_error_code_enum<CalculatorError>: public true_type struct is_error_code_enum<CalculatorError>: public true_type
{}; {};
} }
//= //=
#endif #endif

View file

@ -1,6 +1,5 @@
#define CLS #define CLS
#define MAIN "main.cc" #define MAIN "main.cc"
#define LIBRARY "modules"
#define SOURCES "*.cc" #define SOURCES "*.cc"
#define OBJ_EXT ".o" #define OBJ_EXT ".o"
#define SHAREDREQ "" #define SHAREDREQ ""

View file

@ -0,0 +1,19 @@
#include "main.ih"
int main()
try
{
std::error_code ec = CalculatorError::TypeError;
assert(ec == ErrorSource::CalcError);
assert(ec != ErrorSource::SimError);
assert(ec != ErrorSource::InputError);
ec = CalculatorError::ArityError;
std::cout << ec << ' ' << ec.message() << '\n';
throw std::system_error{ ec, "For demonstration purposes: " };
}
catch (std::system_error &se)
{
std::cout << se.what() << ": " << se.code() << '\n';
}

View file

@ -0,0 +1,11 @@
#include <cassert>
#include <iostream>
// #include <string>
// // #include <unordered_map>
// #include <system_error>
#include "calculatorerror/calculatorerror.h"
#include "simulatorerror/simulatorerror.h"
#include "errorsource/errorsource.h"

View file

@ -3,7 +3,7 @@
#include <system_error> #include <system_error>
//enum //=simerrc
enum class SimulatorError enum class SimulatorError
{ {
// no 0 // no 0
@ -16,6 +16,12 @@ enum class SimulatorError
}; };
//= //=
class SimulatorCategory: public std::error_category
{
char const *name() const noexcept override;
std::string message(int ce) const override;
};
namespace std namespace std
{ {
template <> template <>
@ -23,6 +29,10 @@ namespace std
{}; {};
} }
std::error_code make_error_code(SimulatorError ce);
extern SimulatorCategory const simulatorCategory;
#endif #endif

View file

@ -1,3 +1,8 @@
calculatorerror // specific error categories, defined for this program
simulatorerror calculatorcategory
errorsource simulatorcategory
// classes handling all error conditions
conditioncategory
errorcondition

View file

@ -3,7 +3,7 @@
#include <system_error> #include <system_error>
//calcerrc //enum
enum class CalculatorError enum class CalculatorError
{ {
// no 0, since that's by convention implies no error // no 0, since that's by convention implies no error
@ -16,25 +16,19 @@ enum class CalculatorError
MissingParentheses, // ( and ) don't match MissingParentheses, // ( and ) don't match
}; };
//= //=
//trait
class CalculatorCategory: public std::error_category
{
char const *name() const noexcept override;
std::string message(int ce) const override;
};
extern CalculatorCategory const calculatorCategory;
std::error_code make_error_code(CalculatorError ce);
//calctrait
namespace std namespace std
{ {
template <> template <>
struct is_error_code_enum<CalculatorError>: public true_type struct is_error_code_enum<CalculatorError>: public true_type
{}; {};
} }
//= //=
#endif #endif

View file

@ -6,6 +6,7 @@
#include <string> #include <string>
#include <tuple> #include <tuple>
//class
class ConditionCategory: public std::error_category class ConditionCategory: public std::error_category
{ {
static ConditionCategory *s_instance; static ConditionCategory *s_instance;
@ -25,16 +26,18 @@ class ConditionCategory: public std::error_category
bool equivalent(std::error_code const &code, bool equivalent(std::error_code const &code,
int condition) const noexcept override; int condition) const noexcept override;
// returns condition idx-th name
std::string const &operator[](size_t idx) const;
void addCondition(char const *name, char const *description); void addCondition(char const *name, char const *description);
size_t size() const; size_t size() const;
std::string const &operator[](size_t idx) const;
private: private:
ConditionCategory(); ConditionCategory();
}; };
//=
inline void ConditionCategory::addCondition(char const *name, inline void ConditionCategory::addCondition(char const *name,
char const *description) char const *description)
{ {
d_conditionInfo.push_back({ name, description }); d_conditionInfo.push_back({ name, description });
} }
@ -50,6 +53,3 @@ inline std::string const &ConditionCategory::operator[](size_t idx) const
} }
#endif #endif

View file

@ -5,9 +5,10 @@
// error code and the condition number to verify that the error condition // error code and the condition number to verify that the error condition
// associated with the error_code matches the condition number. // associated with the error_code matches the condition number.
//impl
bool ConditionCategory::equivalent(std::error_code const &ec, int condNr ) bool ConditionCategory::equivalent(std::error_code const &ec, int condNr )
const noexcept const noexcept
{ {
return ec.category().equivalent(ec, condNr); return ec.category().equivalent(ec, condNr);
} }
//=

View file

@ -5,6 +5,7 @@
#include "../conditioncategory/conditioncategory.h" #include "../conditioncategory/conditioncategory.h"
//class
class ErrorCondition class ErrorCondition
{ {
static ErrorCondition *s_instance; static ErrorCondition *s_instance;
@ -31,8 +32,10 @@ class ErrorCondition
private: private:
ErrorCondition(); // singleton, see instance.cc ErrorCondition(); // singleton, see instance.cc
friend std::error_condition make_error_condition(Enum ec);
}; };
//=
std::error_condition make_error_condition(ErrorCondition::Enum ec);
inline std::string const &ErrorCondition::operator[](size_t nr) const inline std::string const &ErrorCondition::operator[](size_t nr) const
{ {

View file

@ -2,7 +2,7 @@
std::error_condition make_error_condition(ErrorCondition::Enum ec) std::error_condition make_error_condition(ErrorCondition::Enum ec)
{ {
return { static_cast<int>(ec), ErrorCondition::instance().d_ec }; return { static_cast<int>(ec), ConditionCategory::instance() };
} }

View file

@ -1,5 +1,6 @@
#define CLS #define CLS
#define MAIN "main.cc" #define MAIN "main.cc"
#define LIBRARY "modules"
#define SOURCES "*.cc" #define SOURCES "*.cc"
#define OBJ_EXT ".o" #define OBJ_EXT ".o"
#define SHAREDREQ "" #define SHAREDREQ ""
@ -9,7 +10,7 @@
#define CXXFLAGS " --std=c++17 -Wall -O2" \ #define CXXFLAGS " --std=c++17 -Wall -O2" \
" -fdiagnostics-color=never " " -fdiagnostics-color=never "
#define IH ".ih" #define IH ".ih"
//#define PRECOMP "-x c++-header" #define PRECOMP "-x c++-header"
#define REFRESH #define REFRESH
#define LDFLAGS "" #define LDFLAGS ""
#define ADD_LIBRARIES "" #define ADD_LIBRARIES ""

View file

@ -1,19 +1,55 @@
#include "main.ih" #include "main.ih"
//demo
int main() int main()
try try
{ {
ErrorCondition &errorCond = ErrorCondition::instance();
std::cerr << CalculatorCategory::instance().name() << '\n' <<
SimulatorCategory::instance().name() << '\n';
errorCond.addCondition("InputCond", "error in user request");
errorCond.addCondition("UnavailCond", "function not available");
errorCond.addCondition("SystemCond", "system failure");
// ec is an actual error code, belonging to some error enum
// the assert checks whether the specified error code belongs to
// the specified error condition
// // also OK: ErrorCondition::Enum{};
// std::error_condition cond = errorCond("InputCond");
std::error_code ec = CalculatorError::TypeError; std::error_code ec = CalculatorError::TypeError;
assert(ec == ErrorSource::CalcError);
assert(ec != ErrorSource::SimError); std::cerr << "Enum value of UnavailCond = " <<
assert(ec != ErrorSource::InputError); errorCond("UnavailCond") << '\n';
assert(ec != ErrorCondition::Enum{});
assert(ec == errorCond("UnavailCond"));
assert(ec != errorCond("SystemCond"));
ec = CalculatorError::MissingParentheses;
assert(ec == errorCond("InputCond"));
ec = CalculatorError::ArityError; ec = CalculatorError::ArityError;
std::cout << ec << ' ' << ec.message() << '\n'; std::cout << ec << ' ' << ec.message() << '\n';
throw std::system_error{ ec, "For demonstration purposes: " }; throw std::system_error{ ec, "For demonstration purposes" };
} }
catch (std::system_error &se) catch (std::system_error const &se)
{ {
std::cout << se.what() << ": " << se.code() << '\n'; std::cout << "System Error: " << se.what() << ":\n"
" " << se.code() << '\n';
//throw; cannot be rethrown!!
} }
/*
Produced output:
calculator
simulator
Enum value of UnavailCond = 2
calculator:4 incorrect number of arguments
System Error: For demonstration purposes: incorrect number of arguments:
calculator:4
*/
//=

View file

@ -1,11 +1,15 @@
#include <cassert> #include <cassert>
#include <iostream> #include <iostream>
// #include <string> #include <string>
// // #include <unordered_map>
// #include <system_error> #include <system_error>
#include "calculatorerror/calculatorerror.h" #include "calculatorerror/calculatorerror.h"
#include "calculatorcategory/calculatorcategory.h"
#include "simulatorerror/simulatorerror.h" #include "simulatorerror/simulatorerror.h"
#include "simulatorcategory/simulatorcategory.h"
#include "errorsource/errorsource.h" #include "errorcondition/errorcondition.h"

View file

@ -9,15 +9,17 @@ try
{ {
std::error_code ec = CalculatorError::ArityError; std::error_code ec = CalculatorError::ArityError;
std::cout << ec << ' ' << ec.message() << '\n'; std::cout << ec << ' ' << ec.message() << '\n';
throw std::system_error{ ec, "For demonstration purposes: " }; throw std::system_error{ ec, "For demonstration purposes" };
} }
catch (std::system_error &se) catch (std::system_error &se)
{ {
std::cout << se.what() << ": " << se.code() << '\n'; std::cout << se.what() << ":\n"
" " << se.code() << '\n';
} }
/* /*
Outputs: Outputs:
calculator:4 incorrect number of arguments calculator:4 incorrect number of arguments
For demonstration purposes: : incorrect number of arguments: calculator:4 For demonstration purposes: incorrect number of arguments:
calculator:4
*/ */

View file

@ -3,7 +3,7 @@
#include <system_error> #include <system_error>
//=simerrc //enum
enum class SimulatorError enum class SimulatorError
{ {
// no 0 // no 0
@ -16,12 +16,6 @@ enum class SimulatorError
}; };
//= //=
class SimulatorCategory: public std::error_category
{
char const *name() const noexcept override;
std::string message(int ce) const override;
};
namespace std namespace std
{ {
template <> template <>
@ -29,10 +23,6 @@ namespace std
{}; {};
} }
std::error_code make_error_code(SimulatorError ce);
extern SimulatorCategory const simulatorCategory;
#endif #endif

View file

@ -1,8 +0,0 @@
// specific error categories, defined for this program
calculatorcategory
simulatorcategory
// classes handling all error conditions
conditioncategory
errorcondition

View file

@ -1,47 +0,0 @@
#include "main.ih"
int main()
try
{
ErrorCondition &errorCond = ErrorCondition::instance();
std::cerr << CalculatorCategory::instance().name() << '\n' <<
SimulatorCategory::instance().name() << '\n';
errorCond.addCondition("InputCond", "error in user request");
errorCond.addCondition("UnavailCond", "function not available");
errorCond.addCondition("SystemCond", "system failure");
// ec is an actual error code, belonging to some error enum
// the assert checks whether the specified error code belongs to
// the specified error condition
// // also OK: ErrorCondition::Enum{};
// std::error_condition cond = errorCond("InputCond");
std::error_code ec = CalculatorError::TypeError;
std::cerr << "Enum value of UnavailCond = " << errorCond("UnavailCond") <<
'\n';
assert(ec != ErrorCondition::Enum{});
assert(ec == errorCond("UnavailCond"));
assert(ec != errorCond("SystemCond"));
ec = CalculatorError::MissingParentheses;
assert(ec == errorCond("InputCond"));
ec = CalculatorError::ArityError;
std::cout << ec << ' ' << ec.message() << '\n';
throw std::system_error{ ec, "For demonstration purposes: " };
}
catch (std::system_error const &se)
{
std::cout << "System Error: " << se.what() << ": " << se.code() << '\n';
//throw; cannot be rethrown!!
}
catch (std::exception const &exc)
{
std::cout << "Exception: " << exc.what() << '\n';
}

View file

@ -1,15 +0,0 @@
#include <cassert>
#include <iostream>
#include <string>
#include <system_error>
#include "calculatorerror/calculatorerror.h"
#include "calculatorcategory/calculatorcategory.h"
#include "simulatorerror/simulatorerror.h"
#include "simulatorcategory/simulatorcategory.h"
#include "errorcondition/errorcondition.h"