C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Enforcements are even more convenient (fixed)

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Gregory
Guest





PostPosted: Fri Dec 29, 2006 10:10 am    Post subject: Enforcements are even more convenient (fixed) Reply with quote



Dear moderators,

I found a bug in my previous post, this is the fixed one. Please post
it.
Thanks,

Gregory
======================================================
In their article published in C/C++ Users Journal, June 2003 Andrei
Alexandrescu and Petru Marginean
(http://www.ddj.com/dept/cpp/184403864) elaborated ENFORCE
macro that exploits policy-based paradigm. The ENFORCE macro enables to
write
error checking code, error message formatting and exception throwing
all in a single line.
Using this macro one can write the following code:

Widget* pWidget = MakeWidget();
ENFORCE(pWidget);

Or even more powerful:
int n = ...;
Widget* pWidget = MakeWidget(n);
ENFORCE(pWidget)("Widget number ")(n)(" is null and it shouldn't!");

The last one will check whether the pWidget is null and if so will
accumulate the formatted error message and finally throw the exception
using the entire message. All this is done behind the scene.

Everything is very cool besides one thing that writing the formatted
string using the templated
operator() is not very convenient and intuitive. I was looking for a
way of re-writing the above ENFORCE code in the more usual and
intuitive way:

ENFORCE(pWidget) << "Widget number " << n << " is null and it
shouldn't!";

It turns out that very small changes to the code presented in the
article and very small overhead
can make the life more happy :-)

Andrei and Petru used the following ENFORCE macro in the article:

#define ENFORCE(exp) \
*MakeEnforcer<DefaultPredicate, DefaultRaiser>(\
(exp), "Expression '" #exp "' failed in '" \
__FILE__ "', line: " STRINGIZE(__LINE__))

In brief (more details can be found in the article) the MakeEnforcer
templated function creates and returns Enforcer object then if error
messages are added with Enforcer::operator() they will be accumulated
within the Enforcer object (only if the exp macro parameter specifies
errorneous expression) and finally Enforcer::operator*() will throw an
exception (again only if necessary).

I suggest small changes to the above macro to achieve the convenience
of << error message formatting. The modified ENFORCE macro and one
small additional class look this way:

class Thrower
{
public:
template<typename Ref, typename P, typename R>
Ref operator = (const Enforcer<Ref, P, R>& enforcer)
{
return *enforcer;
}
};

#define ENFORCE(exp) \
Thrower() = MakeEnforcer<DefaultPredicate, DefaultRaiser>(\
(exp), "Expression '" #exp "' failed in '" \
__FILE__ "', line: " STRINGIZE(__LINE__))

I also replace the templated Enforce::operator() that accumulates error
messages with the templated Enforce::operator<<() that does exactly the
same.

template <class MsgType>
Enforcer& operator<<(const MsgType& msg)
{
// The same code as for former Enforce::operator()
}

The new ENFORCE macro as before will first create Enforcer object then
if error messages are added with Enforcer::operator<<() (that was my
goal) they will be accumulated within the Enforcer object and finally
the Enforcer object is passed to the assignment operator of the Thrower
object (that was created) which in turn will invoke
Enforcer::operator*() to throw an exception (if necessary).

The small overhead in this suggested solution is the creation of an
empty Thrower class and calling its assignment operator. Many of us can
live with it in favour of better readability and convenience of using
operator << instead of () to express error message formatting.

By the way Thrower::operator=() above can be replaced with any binary
operator that has precedence lower than operator << (like <=, +=, *=,
<<= and so on), so to enforce (not the same as above Smile) the right
operators ordering in the ENFORCE macro evaluation.

Regards,

Gregory


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Mathias Gaunard
Guest





PostPosted: Mon Jan 01, 2007 9:47 pm    Post subject: Re: Enforcements are even more convenient (fixed) Reply with quote



Gregory wrote:

Quote:
In their article published in C/C++ Users Journal, June 2003 Andrei
Alexandrescu and Petru Marginean
(http://www.ddj.com/dept/cpp/184403864) elaborated ENFORCE
macro that exploits policy-based paradigm. The ENFORCE macro enables to
write
error checking code, error message formatting and exception throwing
all in a single line.

Is it some kind of new style assert()?

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.