forked from boostorg/iterator
* 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:
@ -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
|
||||||
|
15
test/Jamfile
15
test/Jamfile
@ -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 ]
|
|
||||||
;
|
;
|
||||||
|
Reference in New Issue
Block a user