Pushing fixes over from the trunk to the release branch.

Fixes #5664
Fixes #4874


[SVN r78496]
This commit is contained in:
Ronald Garcia
2012-05-17 14:52:48 +00:00
parent 4bc0a9d40b
commit 05cb2eb119
5 changed files with 183 additions and 136 deletions

View File

@@ -81,7 +81,8 @@ class sub_array;
template <typename T, std::size_t NumDims, typename TPtr = const T*>
class const_sub_array;
template <typename T, typename TPtr, typename NumDims, typename Reference>
template <typename T, typename TPtr, typename NumDims, typename Reference,
typename IteratorCategory>
class array_iterator;
template <typename T, std::size_t NumDims, typename TPtr = const T*>
@@ -251,7 +252,19 @@ struct associated_types
// choose value accessor ends
/////////////////////////////////////////////////////////////////////////
// Due to some imprecision in the C++ Standard,
// MSVC 2010 is broken in debug mode: it requires
// that an Output Iterator have output_iterator_tag in its iterator_category if
// that iterator is not bidirectional_iterator or random_access_iterator.
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
struct mutable_iterator_tag
: boost::random_access_traversal_tag, std::input_iterator_tag
{
operator std::output_iterator_tag() const {
return std::output_iterator_tag();
}
};
#endif
////////////////////////////////////////////////////////////////////////
// multi_array_base
@@ -301,8 +314,16 @@ public:
//
// iterator support
//
typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference> iterator;
typedef array_iterator<T,T const*,mpl::size_t<NumDims>,const_reference> const_iterator;
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1600)
// Deal with VC 2010 output_iterator_tag requirement
typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
mutable_iterator_tag> iterator;
#else
typedef array_iterator<T,T*,mpl::size_t<NumDims>,reference,
boost::random_access_traversal_tag> iterator;
#endif
typedef array_iterator<T,T const*,mpl::size_t<NumDims>,const_reference,
boost::random_access_traversal_tag> const_iterator;
typedef ::boost::reverse_iterator<iterator> reverse_iterator;
typedef ::boost::reverse_iterator<const_iterator> const_reverse_iterator;
@@ -321,7 +342,8 @@ protected:
const size_type* extents,
const index* strides,
const index* index_bases) const {
boost::function_requires<
CollectionConcept<IndexList> >();
ignore_unused_variable_warning(index_bases);
ignore_unused_variable_warning(extents);
#if !defined(NDEBUG) && !defined(BOOST_DISABLE_ASSERTS)
@@ -332,9 +354,15 @@ protected:
#endif
index offset = 0;
for (size_type n = 0; n != NumDims; ++n)
offset += indices[n] * strides[n];
{
typename IndexList::const_iterator i = indices.begin();
size_type n = 0;
while (n != NumDims) {
offset += (*i) * strides[n];
++n;
++i;
}
}
return base[offset];
}

View File

@@ -131,6 +131,7 @@ namespace detail {
function_requires< boost_concepts::WritableIteratorConcept<iterator> >();
function_requires< boost_concepts::ForwardTraversalConcept<const_iterator> >();
function_requires< boost_concepts::ReadableIteratorConcept<const_iterator> >();
function_requires< boost::OutputIterator<iterator,value_type> >();
// RG - a( CollectionArchetype) when available...
value_type vt = a[ id ];

View File

@@ -44,16 +44,18 @@ struct operator_arrow_proxy
mutable T value_;
};
template <typename T, typename TPtr, typename NumDims, typename Reference>
template <typename T, typename TPtr, typename NumDims, typename Reference,
typename IteratorCategory>
class array_iterator;
template <typename T, typename TPtr, typename NumDims, typename Reference>
template <typename T, typename TPtr, typename NumDims, typename Reference,
typename IteratorCategory>
class array_iterator
: public
iterator_facade<
array_iterator<T,TPtr,NumDims,Reference>
array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
, typename associated_types<T,NumDims>::value_type
, boost::random_access_traversal_tag
, IteratorCategory
, Reference
>
, private
@@ -69,7 +71,7 @@ class array_iterator
typedef detail::multi_array::associated_types<T,NumDims> access_t;
typedef iterator_facade<
array_iterator<T,TPtr,NumDims,Reference>
array_iterator<T,TPtr,NumDims,Reference,IteratorCategory>
, typename detail::multi_array::associated_types<T,NumDims>::value_type
, boost::random_access_traversal_tag
, Reference
@@ -79,7 +81,7 @@ class array_iterator
typedef typename access_t::size_type size_type;
#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
template <typename, typename, typename, typename>
template <typename, typename, typename, typename, typename>
friend class array_iterator;
#else
public:
@@ -105,9 +107,9 @@ public:
idx_(idx), base_(base), extents_(extents),
strides_(strides), index_base_(index_base) { }
template <typename OPtr, typename ORef>
template <typename OPtr, typename ORef, typename Cat>
array_iterator(
const array_iterator<T,OPtr,NumDims,ORef>& rhs
const array_iterator<T,OPtr,NumDims,ORef,Cat>& rhs
, typename boost::enable_if_convertible<OPtr,TPtr>::type* = 0
)
: idx_(rhs.idx_), base_(rhs.base_), extents_(rhs.extents_),