* Use boost::referent<> metafunction for detecting the value type of

indirect_iterator.

* Change the order of tests in the Jamfile so expected failures come
  last, accounting for some recent Boost.Build change I suppose.


[SVN r19158]
This commit is contained in:
Dave Abrahams
2003-07-16 19:35:46 +00:00
parent 8a51271e3b
commit 3fe0d4b532
2 changed files with 65 additions and 27 deletions

View File

@ -14,7 +14,12 @@
#include <boost/iterator/iterator_traits.hpp> #include <boost/iterator/iterator_traits.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/python/detail/indirect_traits.hpp> #include <boost/python/detail/indirect_traits.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/apply_if.hpp>
#include <boost/mpl/not.hpp> #include <boost/mpl/not.hpp>
#include <boost/mpl/aux_/has_xxx.hpp> #include <boost/mpl/aux_/has_xxx.hpp>
@ -32,6 +37,9 @@ namespace boost
template <class Iter, class Value, class Category, class Reference, class Difference> template <class Iter, class Value, class Category, class Reference, class Difference>
struct indirect_iterator; struct indirect_iterator;
template <class T>
struct referent;
namespace detail namespace detail
{ {
struct unspecified {}; struct unspecified {};
@ -79,9 +87,10 @@ namespace boost
: mpl::true_ {}; : mpl::true_ {};
# endif # endif
// Metafunction returning the nested element_type typedef // Metafunction accessing the nested ::element_type
template <class T> template <class T>
struct smart_pointer_value : remove_const<typename T::element_type> struct element_type
: mpl::identity<typename T::element_type>
{}; {};
template <class T> template <class T>
@ -110,37 +119,45 @@ namespace boost
struct not_int struct not_int
: not_int_impl<T>::template apply<U> {}; : not_int_impl<T>::template apply<U> {};
template <class Dereferenceable>
struct class_has_element_type
: mpl::and_<
is_class<Dereferenceable>
, has_element_type<Dereferenceable>
>
{};
// If the Value parameter is unspecified, we use this metafunction // If the Value parameter is unspecified, we use this metafunction
// to deduce the default types // to deduce the default types
template <class Iter, class Value, class Category, class Reference, class Difference> template <class Dereferenceable>
struct indirect_base struct default_indirect_value
{ {
typedef typename iterator_value<Iter>::type dereferenceable; typedef typename remove_cv<
typename referent<Dereferenceable>::type
typedef mpl::and_< >::type referent_t;
is_class<dereferenceable>
, has_element_type<dereferenceable>
> is_smart_ptr;
typedef typename mpl::apply_if<
is_smart_ptr
, smart_pointer_value<dereferenceable>
, iterator_value<dereferenceable>
>::type value_type;
typedef typename mpl::if_< typedef typename mpl::if_<
mpl::or_< mpl::or_<
is_smart_ptr class_has_element_type<Dereferenceable>
, iterator_is_mutable<dereferenceable> , iterator_is_mutable<Dereferenceable>
> >
, value_type , referent_t
, value_type const , referent_t const
>::type cv_value_type; >::type type;
};
template <class Iter, class Value, class Category, class Reference, class Difference>
struct indirect_base
{
typedef typename iterator_traits<Iter>::value_type dereferenceable;
typedef iterator_adaptor< typedef iterator_adaptor<
indirect_iterator<Iter, Value, Category, Reference, Difference> indirect_iterator<Iter, Value, Category, Reference, Difference>
, Iter , Iter
, cv_value_type , typename ia_dflt_help<
Value, default_indirect_value<dereferenceable>
>::type
, Category , Category
, Reference , Reference
, Difference , Difference
@ -151,6 +168,20 @@ namespace boost
struct indirect_base<int, int, int, int, int> {}; struct indirect_base<int, int, int, int, int> {};
} // namespace detail } // namespace detail
// User-specializable metafunction which returns the referent of a
// dereferenceable type. The default implementation returns
// Dereferenceable::element_type if such a member exists (thus
// handling the boost smart pointers and auto_ptr), and
// iterator_traits<Dereferenceable>::value_type otherwise.
template <class Dereferenceable>
struct referent
: mpl::apply_if<
detail::class_has_element_type<Dereferenceable>
, detail::element_type<Dereferenceable>
, iterator_value<Dereferenceable>
>
{};
template < template <
class Iterator class Iterator
, class Value = use_default , class Value = use_default

View File

@ -10,7 +10,17 @@ SEARCH on testing.jam = $(BOOST_BUILD_PATH) ;
include testing.jam ; include testing.jam ;
test-suite iterator test-suite iterator
: [ run unit_tests.cpp ] :
# These first two tests will run last, and are expected to fail
# for many less-capable compilers.
[ compile-fail interoperable_fail.cpp ]
# test uses expected success, so that we catch unrelated
# compilation problems.
[ run is_convertible_fail.cpp ]
# These tests should work for just about everything.
[ run unit_tests.cpp ]
[ run concept_tests.cpp ] [ run concept_tests.cpp ]
[ run iterator_adaptor_cc.cpp ] [ run iterator_adaptor_cc.cpp ]
[ run iterator_adaptor_test.cpp ] [ run iterator_adaptor_test.cpp ]
@ -30,7 +40,4 @@ test-suite iterator
[ run ../../utility/reverse_iterator_example.cpp ] [ run ../../utility/reverse_iterator_example.cpp ]
[ run ../../utility/transform_iterator_example.cpp ] [ run ../../utility/transform_iterator_example.cpp ]
[ run is_convertible_fail.cpp ] # test changed to expected success, so that we catch compilation failures.
[ compile-fail interoperable_fail.cpp ]
; ;