
On 12/12/11 13:41, Robert Ramey wrote:
I am trying to implement concept checking for a couple of MPL concepts as part of a large project. I've having a heck of a time with some aspects of this.
The example below illustrates one of the problems I'm having. The intent is to test the concept. for next<I>, the concept
Does ForwardIterator<I> attempt to test that all elements in the iterator, I, satisfy some concept? If so, then I don't see any test for that within the is_end<false_> branch. Are you planning on adding it once you get this immediate problem solved? Maybe the if_recur template shown here: http://svn.boost.org/svn/boost/sandbox/variadic_templates/libs/mpl/sandbox/i... would be some help.
check is invoked recurrsively until the end of iteration is encountered. (I'm assuming it's a list in this test). But the is_end<false_> branch is always invoked leading to failure on both MSVC 9.0 and gcc 4.5.3 compilers
I couldn't get this code to compile with gcc4.7, even after making the modifications shown in the attached. Instead, I get the error message: ramey_iter_concept_check.cpp:34:10: error: invalid explicit specialization before '>' token ramey_iter_concept_check.cpp:34:10: error: enclosing class templates are not explicitly specialized ramey_iter_concept_check.cpp:35:28: error: template parameters not used in partial specialization: ramey_iter_concept_check.cpp:35:28: error: 'I' The reason the specialization was moved outside of the containing class was because gcc said you couldn't specialize a nested template in the class declaration; however, even when the is_end specialization was moved outside the class declaration, the above error message occurred. I'm surprised gcc 4.5.3 compiles your code because, IIRC, the problem of nested template specializations has been around for some time.
I'll be quite impressed with anyone who can figure out how to make this work.
Robert Ramey
template<typename I> struct ForwardIterator { template<typename B> struct is_end {}; template<> struct is_end<false_> { typedef typename deref<I>::type t1; typedef typename next<I>::type t2; BOOST_CONCEPT_ASSERT(( ForwardIterator<t2> )); }; typedef typename boost::mpl::print< I >::type t1; typedef typename is_end< typename boost::is_same< boost::mpl::l_iter<boost::mpl::l_end>, I > > type; BOOST_MPL_ASSERT(( is_convertible< typename I::category, forward_iterator_tag > )); };
template<typename S> struct ForwardSequence { typedef typename end<S>::type t2; BOOST_CONCEPT_ASSERT(( ForwardIterator<t2> )); };
#include <boost/mpl/list.hpp> void test_list_sequence(){ BOOST_CONCEPT_ASSERT(( boost::mpl::ForwardSequence< boost::mpl::list<int, char> > )); }