[c++11] compile_if utility

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: #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...

On Wed, Jul 4, 2012 at 10:39 AM, Lorenzo Caminiti <lorcaminiti@gmail.com> 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

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?
If C++11 had local class templates, then you could write a macro that emits the declaration of a local class template with a bool template parameter with a static function that performs the assert (for the true specialization) or does nothing (for the false specialization), and then call it with the condition as the template parameter. Are there any compilers that support local class templates and/or local classes with template members as an extension? I have repeatedly found myself wishing for them, and they seem like a logical next step after adding support for local classes as template parameters in C++11. Regards, Nate

On Wed, Jul 4, 2012 at 1:23 PM, Nathan Ridge <zeratul976@hotmail.com> wrote:
If C++11 had local class templates, then you could write a macro that emits the declaration of a local class template with a bool template parameter with a static function that performs the assert (for the true specialization) or does nothing (for the false specialization), and then call it with the condition as the template parameter.
Yeah, that'd be cool and we could implement polimorphic local functions. The same goes for lambas -- it'd be nice to have templated lambdas.
Are there any compilers that support local class templates and/or local classes with template members as an extension? I have repeatedly found
AFAIK, no :(
myself wishing for them, and they seem like a logical next step after adding support for local classes as template parameters in C++11.
--Lorenzo
participants (3)
-
Lorenzo Caminiti
-
Mathias Gaunard
-
Nathan Ridge