forked from boostorg/iterator
Fixed crt issue. Make transform_iterator work with function pointers.
[SVN r1404]
This commit is contained in:
@@ -31,6 +31,20 @@ namespace boost
|
|||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
|
|
||||||
|
template <class UnaryFunction>
|
||||||
|
struct result
|
||||||
|
{
|
||||||
|
typedef typename UnaryFunction::result_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
|
template <class Return, class Argument>
|
||||||
|
struct result<Return(*)(Argument)>
|
||||||
|
{
|
||||||
|
typedef Return type;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
// Given the transform iterator's transformation and iterator, this
|
// Given the transform iterator's transformation and iterator, this
|
||||||
// is the type used as its traits.
|
// is the type used as its traits.
|
||||||
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
template <class UnaryFunction, class Iterator, class Reference, class Value>
|
||||||
@@ -43,9 +57,17 @@ namespace boost
|
|||||||
BOOST_STATIC_ASSERT((is_tag< readable_iterator_tag, typename access_category<Iterator>::type >::value));
|
BOOST_STATIC_ASSERT((is_tag< readable_iterator_tag, typename access_category<Iterator>::type >::value));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef typename UnaryFunction::result_type result_type;
|
typedef typename mpl::apply_if<
|
||||||
|
is_same< Reference, use_default >
|
||||||
|
, result<UnaryFunction>
|
||||||
|
, mpl::identity<Reference>
|
||||||
|
>::type result_type;
|
||||||
|
|
||||||
typedef typename remove_reference< result_type >::type cv_value_type;
|
typedef typename mpl::if_<
|
||||||
|
is_same< Value, use_default >
|
||||||
|
, typename remove_reference< result_type >::type
|
||||||
|
, Value
|
||||||
|
>::type cv_value_type;
|
||||||
|
|
||||||
typedef typename mpl::if_<
|
typedef typename mpl::if_<
|
||||||
is_reference< result_type >
|
is_reference< result_type >
|
||||||
@@ -64,7 +86,7 @@ namespace boost
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
typedef iterator_adaptor<
|
typedef iterator_adaptor<
|
||||||
transform_iterator<UnaryFunction, Iterator>
|
transform_iterator<UnaryFunction, Iterator, Reference, Value>
|
||||||
, Iterator
|
, Iterator
|
||||||
, cv_value_type
|
, cv_value_type
|
||||||
, iterator_tag<
|
, iterator_tag<
|
||||||
@@ -95,7 +117,7 @@ namespace boost
|
|||||||
|
|
||||||
template<class OtherIterator>
|
template<class OtherIterator>
|
||||||
transform_iterator(
|
transform_iterator(
|
||||||
transform_iterator<UnaryFunction, OtherIterator> const& t
|
transform_iterator<UnaryFunction, OtherIterator, Reference, Value> const& t
|
||||||
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
, typename enable_if_convertible<OtherIterator, Iterator>::type* = 0
|
||||||
)
|
)
|
||||||
: super_t(t.base()), m_f(t.functor()) {}
|
: super_t(t.base()), m_f(t.functor()) {}
|
||||||
@@ -112,20 +134,20 @@ namespace boost
|
|||||||
UnaryFunction m_f;
|
UnaryFunction m_f;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class UnaryFunctionObject, class Iterator>
|
template <class UnaryFunction, class Iterator>
|
||||||
transform_iterator<UnaryFunctionObject, Iterator> make_transform_iterator(Iterator it, UnaryFunctionObject fun)
|
transform_iterator<UnaryFunction, Iterator> make_transform_iterator(Iterator it, UnaryFunction fun)
|
||||||
{
|
{
|
||||||
return transform_iterator<UnaryFunctionObject, Iterator>(it, fun);
|
return transform_iterator<UnaryFunction, Iterator>(it, fun);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||||
template <class Return, class Argument, class Iterator>
|
template <class Return, class Argument, class Iterator>
|
||||||
transform_iterator< function1<Return, Argument>, Iterator>
|
transform_iterator< Return (*)(Argument), Iterator, Return>
|
||||||
make_transform_iterator(Iterator it, Return (*fun)(Argument))
|
make_transform_iterator(Iterator it, Return (*fun)(Argument))
|
||||||
{
|
{
|
||||||
typedef function1<Return, Argument> function_t;
|
return transform_iterator<Return (*)(Argument), Iterator, Return>(it, fun);
|
||||||
|
|
||||||
return transform_iterator<function_t, Iterator>(it, function_t(fun));
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
|
|
||||||
|
@@ -43,8 +43,6 @@ namespace boost { namespace detail
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct mult_functor {
|
struct mult_functor {
|
||||||
typedef int result_type;
|
|
||||||
typedef int argument_type;
|
|
||||||
// Functors used with transform_iterator must be
|
// Functors used with transform_iterator must be
|
||||||
// DefaultConstructible, as the transform_iterator must be
|
// DefaultConstructible, as the transform_iterator must be
|
||||||
// DefaultConstructible to satisfy the requirements for
|
// DefaultConstructible to satisfy the requirements for
|
||||||
@@ -55,6 +53,19 @@ struct mult_functor {
|
|||||||
int a;
|
int a;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct adaptable_mult_functor
|
||||||
|
: mult_functor
|
||||||
|
{
|
||||||
|
typedef int result_type;
|
||||||
|
typedef int argument_type;
|
||||||
|
// Functors used with transform_iterator must be
|
||||||
|
// DefaultConstructible, as the transform_iterator must be
|
||||||
|
// DefaultConstructible to satisfy the requirements for
|
||||||
|
// TrivialIterator.
|
||||||
|
adaptable_mult_functor() { }
|
||||||
|
adaptable_mult_functor(int aa) : mult_functor(aa) { }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct select_first
|
struct select_first
|
||||||
{
|
{
|
||||||
@@ -108,8 +119,8 @@ main()
|
|||||||
|
|
||||||
// Concept checks
|
// Concept checks
|
||||||
{
|
{
|
||||||
typedef boost::transform_iterator<mult_functor, int*> iter_t;
|
typedef boost::transform_iterator<adaptable_mult_functor, int*> iter_t;
|
||||||
typedef boost::transform_iterator<mult_functor, int const*> c_iter_t;
|
typedef boost::transform_iterator<adaptable_mult_functor, int const*> c_iter_t;
|
||||||
|
|
||||||
boost::function_requires< boost_concepts::InteroperableConcept<iter_t, c_iter_t> >();
|
boost::function_requires< boost_concepts::InteroperableConcept<iter_t, c_iter_t> >();
|
||||||
}
|
}
|
||||||
@@ -124,7 +135,25 @@ main()
|
|||||||
for (int k2 = 0; k2 < N; ++k2)
|
for (int k2 = 0; k2 < N; ++k2)
|
||||||
x[k2] = x[k2] * 2;
|
x[k2] = x[k2] * 2;
|
||||||
|
|
||||||
typedef boost::transform_iterator<mult_functor, int*> iter_t;
|
typedef boost::transform_iterator<adaptable_mult_functor, int*> iter_t;
|
||||||
|
iter_t i(y, adaptable_mult_functor(2));
|
||||||
|
boost::input_iterator_test(i, x[0], x[1]);
|
||||||
|
boost::input_iterator_test(iter_t(&y[0], adaptable_mult_functor(2)), x[0], x[1]);
|
||||||
|
|
||||||
|
boost::random_access_readable_iterator_test(i, N, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test transform_iterator non adaptable functor
|
||||||
|
{
|
||||||
|
int x[N], y[N];
|
||||||
|
for (int k = 0; k < N; ++k)
|
||||||
|
x[k] = k;
|
||||||
|
std::copy(x, x + N, y);
|
||||||
|
|
||||||
|
for (int k2 = 0; k2 < N; ++k2)
|
||||||
|
x[k2] = x[k2] * 2;
|
||||||
|
|
||||||
|
typedef boost::transform_iterator<mult_functor, int*, int> iter_t;
|
||||||
iter_t i(y, mult_functor(2));
|
iter_t i(y, mult_functor(2));
|
||||||
boost::input_iterator_test(i, x[0], x[1]);
|
boost::input_iterator_test(i, x[0], x[1]);
|
||||||
boost::input_iterator_test(iter_t(&y[0], mult_functor(2)), x[0], x[1]);
|
boost::input_iterator_test(iter_t(&y[0], mult_functor(2)), x[0], x[1]);
|
||||||
@@ -132,6 +161,27 @@ main()
|
|||||||
boost::random_access_readable_iterator_test(i, N, x);
|
boost::random_access_readable_iterator_test(i, N, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Test transform_iterator default argument handling
|
||||||
|
{
|
||||||
|
{
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int*, float> iter_t;
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, float>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, float>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int*, boost::use_default, float> iter_t;
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, int>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, float>::value));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
typedef boost::transform_iterator<adaptable_mult_functor, int*, float, double> iter_t;
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::reference, float>::value));
|
||||||
|
BOOST_STATIC_ASSERT((boost::is_same<iter_t::value_type, double>::value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Test transform_iterator with function pointers
|
// Test transform_iterator with function pointers
|
||||||
{
|
{
|
||||||
int x[N], y[N];
|
int x[N], y[N];
|
||||||
|
Reference in New Issue
Block a user