Boost logo

Boost :

Subject: Re: [boost] [c++11] compile_if utility
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-07-04 10:48:28


On Wed, Jul 4, 2012 at 10:39 AM, Lorenzo Caminiti <lorcaminiti_at_[hidden]> wrote:
> Hello all,
>
> I was thinking how to program assertion requirements in C++11. I need
> to program something like this
>
> if "has_equal_to<T>" then "assert(back() == value)"
> else do nothing, don't even compile "assert(back() == value)"
>
> Using C++11 lambdas, I was able to program a compile_if utility to do
> the following:
>
> compile_if< boost::has_equal_to<T> >([&]() {
> assert(this->back() == value); // compiled and executed iff
> has_equal_to<T>
> });
>
> Any interest in adding compile_if to Boost.Utility? It could be
> renamed exec_if if compile_if is too "strong".
>
> I didn't play with compile_if much so there might cases where it
> doesn't work... but I wanted to share it with the ML anyway:

Yep, I spoke too soon :( The code compiles on G++ 4.5.3 -std=c++0x but
it does not compile on MSVC10 which complains x has no operator==...
who's right? (I'm afraid MVSC...).

If so, is there another way to do this in C++11?

> #include <boost/type_traits.hpp>
> #include <cassert>
> #include <vector>
> #include <iostream>
>
> template< bool Boolean >
> struct compile_if_c
> {
> template< typename UnaryFunc >
> compile_if_c ( UnaryFunc f )
> {
> std::cout << "compiling" << std::endl;
> f();
> }
> };
>
> template< >
> struct compile_if_c <false>
> {
> compile_if_c ( ... )
> {
> std::cout << "not compiling" << std::endl;
> }
> };
>
> template< class BooleanMetafunc, class UnaryFunc >
> void compile_if ( UnaryFunc f )
> {
> compile_if_c<BooleanMetafunc::value> compile(f);
> }
>
> template< typename T >
> class vector
> {
> public: typedef typename std::vector<T>::const_reference const_reference;
>
> public: void push_back ( T const& value )
> {
> vector_.push_back(value);
> compile_if< boost::has_equal_to<T> >([&]() {
> assert(this->back() == value);
> });
> }
>
> public: const_reference back ( void ) const
> {
> return vector_.back();
> }
>
> private: std::vector<T> vector_;
> };
>
> struct x {}; // no operator==
>
> int main ( void )
> {
> vector<x>().push_back(x()); // no == so skip assertion back() == value
> vector<int>().push_back(123); // has == so assert back() == value
> return 0;
> }
>
> Thanks.
> --Lorenzo
>
> P.S. Eh, if C++11 lambda had constant captures [const&](){
> assert(this->back() == value; } I could have even made the assertion
> constant-correct...

-- 
--Lorenzo

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk