Design by Contract with Lambdas and template magic
{ edited by mod to shorten lines to ~70 characters. -mod }
Hello,
I want to share what i think is a pretty neat piece of code to
have a nice syntax for design by contract with Preconditions
and Postconditions.
double SqrtRoot(double d)
{
return contract(
[&](){ return d>=0;},
[&](){ return sqrt(d);},
[](double ret){ return ret>=0;}
);
}
Best of all, this is C++11 Standard conformant. I am interested
in people checking performance and flexibility (for example
function objects of function pointers instead of lambdas).
Possible deactivation of checking for release builds (NDEBUG
and template specialisation)
Throwing of exceptions, and customization hooks.
Use for invariant checking.
And of course things I have not thought about.
This is the code for the contract function template:
template <typename T>
struct Lambda_Return: public Lambda_Return<decltype(&T::operator())>
{ };
template <typename ClassType, typename ReturnType, typename... Args>
struct Lambda_Return<ReturnType(ClassType::*)(Args...) const>
{
typedef ReturnType return_t;
};
template <typename T>
using Lambda_Ret = typename Lambda_Return<T>::return_t;
template <typename PRE, typename FUNC, typename POST>
struct ContractHelper
{
private:
PRE Precondition;
FUNC Function;
POST Postcondition;
typedef Lambda_Ret<FUNC> ReturnType;
public:
ContractHelper(PRE pre, FUNC func, POST post):
Precondition(pre),
Function(func),
Postcondition(post)
{ }
operator ReturnType()
{
if (!Precondition()) {
std::cout<<"Precondition violated!";
std::cin.get();
exit(1);
}
auto ret=Function();
if (!Postcondition(ret)) {
std::cout<<"Postcondition violated!";
std::cin.get();
exit(1);
}
return ret;
}
};
template <typename PRE, typename FUNC, typename POST>
Lambda_Ret<FUNC> contract(PRE pre, FUNC func, POST post)
{ return ContractHelper<PRE, FUNC, POST>{pre, func, post}; }
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]