Boost logo

Boost :

From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2006-05-16 06:27:58


WHAT:
=====

An instantiation of "begin<T>::type" fails to compile if T is an MPL Integral Constant. 'begin' is supposed to return 'void_' for all types that do not model the MPL Sequence concept. The bug also
causes 'is_sequence' to fail.

FILES:
======

- begin_end_impl.hpp.patch

    changes needed to make things work like documented

- is_sequence.cpp.patch

    inclusion of the problematic case in the test suite

diffed against: CVS HEAD

TESTED WITH:
============

- MSVC 8.0
- MSVC 7.1
- GCC 3.4.2

Index: boost/mpl/aux_/begin_end_impl.hpp
===================================================================
RCS file: /cvsroot/boost/boost/boost/mpl/aux_/begin_end_impl.hpp,v
retrieving revision 1.8
diff -u -r1.8 begin_end_impl.hpp
--- boost/mpl/aux_/begin_end_impl.hpp 2 Sep 2004 15:40:43 -0000 1.8
+++ boost/mpl/aux_/begin_end_impl.hpp 15 May 2006 23:22:17 -0000
@@ -17,12 +17,30 @@
 #include <boost/mpl/begin_end_fwd.hpp>
 #include <boost/mpl/sequence_tag_fwd.hpp>
 #include <boost/mpl/void.hpp>
+#include <boost/mpl/eval_if.hpp>
+#include <boost/mpl/aux_/has_begin.hpp>
 #include <boost/mpl/aux_/na.hpp>
 #include <boost/mpl/aux_/traits_lambda_spec.hpp>
 #include <boost/mpl/aux_/config/eti.hpp>
 
 namespace boost { namespace mpl {
 
+
+namespace aux {
+
+template< typename Sequence >
+struct begin_type
+{
+ typedef typename Sequence::begin type;
+};
+template< typename Sequence >
+struct end_type
+{
+ typedef typename Sequence::end type;
+};
+
+}
+
 // default implementation; conrete sequences might override it by
 // specializing either the 'begin_impl/end_impl' or the primary
 // 'begin/end' templates
@@ -32,7 +50,8 @@
 {
     template< typename Sequence > struct apply
     {
- typedef typename Sequence::begin type;
+ typedef typename eval_if<aux::has_begin<Sequence, true_>,
+ aux::begin_type<Sequence>, void_>::type type;
     };
 };
 
@@ -41,7 +60,8 @@
 {
     template< typename Sequence > struct apply
     {
- typedef typename Sequence::end type;
+ typedef typename eval_if<aux::has_begin<Sequence, true_>,
+ aux::end_type<Sequence>, void_>::type type;
     };
 };
 

Index: libs/mpl/test/is_sequence.cpp
===================================================================
RCS file: /cvsroot/boost/boost/libs/mpl/test/is_sequence.cpp,v
retrieving revision 1.5
diff -u -r1.5 is_sequence.cpp
--- libs/mpl/test/is_sequence.cpp 2 Sep 2004 15:41:35 -0000 1.5
+++ libs/mpl/test/is_sequence.cpp 15 May 2006 22:55:40 -0000
@@ -12,6 +12,7 @@
 // $Revision: 1.5 $
 
 #include <boost/mpl/is_sequence.hpp>
+#include <boost/mpl/int.hpp>
 #include <boost/mpl/list.hpp>
 #include <boost/mpl/vector.hpp>
 #include <boost/mpl/range_c.hpp>
@@ -25,6 +26,7 @@
 MPL_TEST_CASE()
 {
     MPL_ASSERT_NOT(( is_sequence< std_vector<int> > ));
+ MPL_ASSERT_NOT(( is_sequence< int_<0> > ));
     MPL_ASSERT_NOT(( is_sequence< int > ));
     MPL_ASSERT_NOT(( is_sequence< int& > ));
     MPL_ASSERT_NOT(( is_sequence< UDT > ));


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