FIX work around VC7.1 and 8.0 problems with function template ambiguity
- use a lot of class template partial specialistion to help 'simplify' the template arguments
This commit is contained in:
parent
c5a127d986
commit
5be4c2382a
@ -35,22 +35,25 @@
|
||||
// Microsoft Visual C++
|
||||
#if defined (BOOST_MSVC) && ! defined (BOOST_STRICT_CONFIG)
|
||||
|
||||
// Version 6.0 & 7.0
|
||||
// Version 6.0 and 7.0
|
||||
#if BOOST_MSVC <= 1300
|
||||
#define BOOST_UBLAS_UNSUPPORTED_COMPILER
|
||||
#endif
|
||||
|
||||
// Version 7.1
|
||||
#if BOOST_MSVC == 1310
|
||||
|
||||
// Seeming still some problems with function templates
|
||||
#define BOOST_UBLAS_MSVC71_FUNCTION_TEMPLATE_ORDERING
|
||||
// One of these workarounds is needed for MSVC 7.1 AFAIK
|
||||
// (thanks to John Maddock and Martin Lauer).
|
||||
#if !(defined(BOOST_UBLAS_NO_NESTED_CLASS_RELATION) || defined(BOOST_UBLAS_MSVC_NESTED_CLASS_RELATION))
|
||||
#define BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
||||
#endif
|
||||
|
||||
// Version 7.1 and 8.0
|
||||
#if BOOST_MSVC <= 1400
|
||||
// Seeming still some problems with function templates
|
||||
#define BOOST_UBLAS_MSVC_FUNCTION_TEMPLATE_ORDERING
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -3149,6 +3149,9 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
typename matrix_range<M>::matrix_type matrix_range<M>::nil_;
|
||||
|
||||
// Projections
|
||||
#ifndef BOOST_UBLAS_MSVC_FUNCTION_TEMPLATE_ORDERING
|
||||
// ISSUE MSVC cannot disambiguate the second function template argument
|
||||
// - to work around this we define the project functions later using some helper classes
|
||||
template<class M>
|
||||
BOOST_UBLAS_INLINE
|
||||
matrix_range<M> project (M &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
|
||||
@ -3170,8 +3173,9 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
const matrix_range<M> project (const matrix_range<M> &data, const typename matrix_range<M>::range_type &r1, const typename matrix_range<M>::range_type &r2) {
|
||||
return data.project (r1, r2);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Specialize temporary
|
||||
// Specialization of temporary_traits
|
||||
template <class M>
|
||||
struct matrix_temporary_traits< matrix_range<M> >
|
||||
: matrix_temporary_traits< M > {} ;
|
||||
@ -4045,6 +4049,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
typename matrix_slice<M>::matrix_type matrix_slice<M>::nil_;
|
||||
|
||||
// Projections
|
||||
#ifndef BOOST_UBLAS_MSVC_FUNCTION_TEMPLATE_ORDERING
|
||||
template<class M>
|
||||
BOOST_UBLAS_INLINE
|
||||
matrix_slice<M> project (M &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
|
||||
@ -4056,7 +4061,6 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
// ISSUE was: return matrix_slice<M> (const_cast<M &> (data), s1, s2);
|
||||
return matrix_slice<const M> (data, s1, s2);
|
||||
}
|
||||
#ifndef BOOST_UBLAS_MSVC71_FUNCTION_TEMPLATE_ORDERING
|
||||
template<class M>
|
||||
BOOST_UBLAS_INLINE
|
||||
matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_slice<M>::range_type &r1, const typename matrix_slice<M>::range_type &r2) {
|
||||
@ -4067,7 +4071,6 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
const matrix_slice<M> project (const matrix_slice<M> &data, const typename matrix_slice<M>::range_type &r1, const typename matrix_slice<M>::range_type &r2) {
|
||||
return data.project (r1, r2);
|
||||
}
|
||||
#endif
|
||||
template<class M>
|
||||
BOOST_UBLAS_INLINE
|
||||
matrix_slice<M> project (matrix_slice<M> &data, const typename matrix_slice<M>::slice_type &s1, const typename matrix_slice<M>::slice_type &s2) {
|
||||
@ -4079,7 +4082,119 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
return data.project (s1, s2);
|
||||
}
|
||||
|
||||
/// Specialization of temporary_traits
|
||||
#else
|
||||
// ISSUE MSVC cannot disambiguate the second function template argument
|
||||
// - to work around this using some helper classes
|
||||
namespace {
|
||||
template <class M>
|
||||
struct msvc_mproject_helper
|
||||
{
|
||||
typedef typename matrix_range<M>::range_type range_type;
|
||||
typedef typename matrix_slice<M>::slice_type slice_type;
|
||||
template <class RS>
|
||||
struct return_type {
|
||||
};
|
||||
template <>
|
||||
struct return_type<range_type> {
|
||||
typedef matrix_range<M> type;
|
||||
};
|
||||
template <>
|
||||
struct return_type<slice_type> {
|
||||
typedef matrix_slice<M> type;
|
||||
};
|
||||
BOOST_UBLAS_INLINE
|
||||
static matrix_range<M> apply (M &data, const range_type &r1, const range_type &r2) {
|
||||
return matrix_range<M> (data, r1, r2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const matrix_range<M> apply (const M &data, const range_type &r1, const range_type &r2) {
|
||||
return matrix_range<M> (data, r1, r2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static matrix_slice<M> apply (M &data, const slice_type &s1, const slice_type &s2) {
|
||||
return matrix_slice<M> (data, s1, s2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const matrix_slice<M> apply (const M &data, const slice_type &s1, const slice_type &s2) {
|
||||
return const matrix_slice<M> (data, s1, s2);
|
||||
}
|
||||
};
|
||||
template <class M>
|
||||
struct msvc_mproject_helper< matrix_range<M> >
|
||||
{
|
||||
typedef typename matrix_range<M> base_type;
|
||||
typedef typename matrix_range<M>::range_type range_type;
|
||||
typedef typename matrix_slice<M>::slice_type slice_type;
|
||||
template <class RS>
|
||||
struct return_type {
|
||||
};
|
||||
template <>
|
||||
struct return_type<range_type> {
|
||||
typedef matrix_range<M> type;
|
||||
};
|
||||
template <>
|
||||
struct return_type<slice_type> {
|
||||
typedef matrix_slice<base_type> type; // no special proxy created for a slice of a range
|
||||
};
|
||||
BOOST_UBLAS_INLINE
|
||||
static base_type apply (base_type &data, const range_type &r1, const range_type &r2) {
|
||||
return data.project (r1, r2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const base_type apply (const base_type &data, const range_type &r1, const range_type &r) {
|
||||
return data.project (r1, r2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static matrix_slice<base_type> apply (base_type &data, const slice_type &s1, const slice_type &s2) {
|
||||
return matrix_slice<base_type> (data, s1, s2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const matrix_slice<base_type> apply (const base_type &data, const slice_type &s1, const slice_type &s2) {
|
||||
return const matrix_slice<const base_type> (data, s1, s2);
|
||||
}
|
||||
};
|
||||
template <class M>
|
||||
struct msvc_mproject_helper< matrix_slice<M> >
|
||||
{
|
||||
typedef typename matrix_slice<M> base_type;
|
||||
typedef typename matrix_slice<M>::range_type range_type;
|
||||
typedef typename matrix_slice<M>::slice_type slice_type;
|
||||
template <class RS>
|
||||
struct return_type {
|
||||
typedef matrix_slice<M> type;
|
||||
};
|
||||
BOOST_UBLAS_INLINE
|
||||
static matrix_slice<M> apply (base_type &data, const range_type &r1, const range_type &r2) {
|
||||
return data.project (r1, r2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const matrix_slice<M> apply (const base_type &data, const range_type &r1, const range_type &r2) {
|
||||
return data.project (r1, r2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static matrix_slice<M> apply (base_type &data, const slice_type &s1, const slice_type &s2) {
|
||||
return data.project (s1, s2);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const matrix_slice<M> apply (const base_type &data, const slice_type &s1, const slice_type &s2) {
|
||||
return data.project (s1, s2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<class M, class RS>
|
||||
BOOST_UBLAS_INLINE
|
||||
typename msvc_mproject_helper<M>::template return_type<RS>::type project (M &data, const RS &rs1, const RS &rs2) {
|
||||
return msvc_mproject_helper<M>::apply (data, rs1, rs2);
|
||||
}
|
||||
template<class M, class RS>
|
||||
BOOST_UBLAS_INLINE
|
||||
const typename msvc_mproject_helper<M>::template return_type<RS>::type project (const M &data, const RS &rs1, const RS &rs2) {
|
||||
return msvc_mproject_helper<const M>::apply (data, rs1, rs2);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Specialization of temporary_traits
|
||||
template <class M>
|
||||
struct matrix_temporary_traits< matrix_slice<M> >
|
||||
: matrix_temporary_traits< M > {};
|
||||
|
@ -479,14 +479,17 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
typename vector_range<V>::vector_type vector_range<V>::nil_;
|
||||
|
||||
// Projections
|
||||
#ifndef BOOST_UBLAS_MSVC_FUNCTION_TEMPLATE_ORDERING
|
||||
// ISSUE MSVC cannot disambiguate the second function template argument
|
||||
// - to work around this we define the project functions later using some helper classes
|
||||
template<class V>
|
||||
BOOST_UBLAS_INLINE
|
||||
vector_range<V> project (V &data, const typename vector_range<V>::range_type &r) {
|
||||
vector_range<V> project (V &data, typename vector_range<V>::range_type const &r) {
|
||||
return vector_range<V> (data, r);
|
||||
}
|
||||
template<class V>
|
||||
BOOST_UBLAS_INLINE
|
||||
const vector_range<const V> project (const V &data, const typename vector_range<V>::range_type &r) {
|
||||
const vector_range<const V> project (const V &data, typename vector_range<V>::range_type const &r) {
|
||||
// ISSUE was: return vector_range<V> (const_cast<V &> (data), r);
|
||||
return vector_range<const V> (data, r);
|
||||
}
|
||||
@ -500,6 +503,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
const vector_range<V> project (const vector_range<V> &data, const typename vector_range<V>::range_type &r) {
|
||||
return data.project (r);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Specialization of temporary_traits
|
||||
template <class V>
|
||||
@ -969,6 +973,7 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
typename vector_slice<V>::vector_type vector_slice<V>::nil_;
|
||||
|
||||
// Projections
|
||||
#ifndef BOOST_UBLAS_MSVC_FUNCTION_TEMPLATE_ORDERING
|
||||
template<class V>
|
||||
BOOST_UBLAS_INLINE
|
||||
vector_slice<V> project (V &data, const typename vector_slice<V>::slice_type &s) {
|
||||
@ -990,7 +995,6 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
const vector_slice<V> project (const vector_slice<V> &data, const typename vector_slice<V>::slice_type &s) {
|
||||
return data.project (s);
|
||||
}
|
||||
#ifndef BOOST_UBLAS_MSVC71_FUNCTION_TEMPLATE_ORDERING
|
||||
template<class V>
|
||||
BOOST_UBLAS_INLINE
|
||||
vector_slice<V> project (vector_slice<V> &data, const typename vector_slice<V>::range_type &r) {
|
||||
@ -1001,6 +1005,117 @@ namespace boost { namespace numeric { namespace ublas {
|
||||
const vector_slice<V> project (const vector_slice<V> &data, const typename vector_slice<V>::range_type &r) {
|
||||
return data.project (r);
|
||||
}
|
||||
|
||||
#else
|
||||
// ISSUE MSVC cannot disambiguate the second function template argument
|
||||
// - to work around this using some helper classes
|
||||
namespace {
|
||||
template <class V>
|
||||
struct msvc_vproject_helper
|
||||
{
|
||||
typedef typename vector_range<V>::range_type range_type;
|
||||
typedef typename vector_slice<V>::slice_type slice_type;
|
||||
template <class RS>
|
||||
struct return_type {
|
||||
};
|
||||
template <>
|
||||
struct return_type<range_type> {
|
||||
typedef vector_range<V> type;
|
||||
};
|
||||
template <>
|
||||
struct return_type<slice_type> {
|
||||
typedef vector_slice<V> type;
|
||||
};
|
||||
BOOST_UBLAS_INLINE
|
||||
static vector_range<V> apply (V &data, const range_type &r) {
|
||||
return vector_range<V> (data, r);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const vector_range<V> apply (const V &data, const range_type &r) {
|
||||
return vector_range<V> (data, r);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static vector_slice<V> apply (V &data, const slice_type &s) {
|
||||
return vector_slice<V> (data, s);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const vector_slice<V> apply (const V &data, const slice_type &s) {
|
||||
return const vector_slice<V> (data, s);
|
||||
}
|
||||
};
|
||||
template <class V>
|
||||
struct msvc_vproject_helper< vector_range<V> >
|
||||
{
|
||||
typedef typename vector_range<V> base_type;
|
||||
typedef typename vector_range<V>::range_type range_type;
|
||||
typedef typename vector_slice<V>::slice_type slice_type;
|
||||
template <class RS>
|
||||
struct return_type {
|
||||
};
|
||||
template <>
|
||||
struct return_type<range_type> {
|
||||
typedef vector_range<V> type;
|
||||
};
|
||||
template <>
|
||||
struct return_type<slice_type> {
|
||||
typedef vector_slice<base_type> type; // no special proxy created for a slice of a range
|
||||
};
|
||||
BOOST_UBLAS_INLINE
|
||||
static base_type apply (base_type &data, const range_type &r) {
|
||||
return data.project (r);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const base_type apply (const base_type &data, const range_type &r) {
|
||||
return data.project (r);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static vector_slice<base_type> apply (base_type &data, const slice_type &s) {
|
||||
return vector_slice<base_type> (data, s);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const vector_slice<base_type> apply (const base_type &data, const slice_type &s) {
|
||||
return const vector_slice<const base_type> (data, s);
|
||||
}
|
||||
};
|
||||
template <class V>
|
||||
struct msvc_vproject_helper< vector_slice<V> >
|
||||
{
|
||||
typedef typename vector_slice<V> base_type;
|
||||
typedef typename vector_slice<V>::range_type range_type;
|
||||
typedef typename vector_slice<V>::slice_type slice_type;
|
||||
template <class RS>
|
||||
struct return_type {
|
||||
typedef vector_slice<V> type;
|
||||
};
|
||||
BOOST_UBLAS_INLINE
|
||||
static vector_slice<V> apply (base_type &data, const range_type &r) {
|
||||
return data.project (r);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const vector_slice<V> apply (const base_type &data, const range_type &r) {
|
||||
return data.project (r);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static vector_slice<V> apply (base_type &data, const slice_type &s) {
|
||||
return data.project (s);
|
||||
}
|
||||
BOOST_UBLAS_INLINE
|
||||
static const vector_slice<V> apply (const base_type &data, const slice_type &s) {
|
||||
return data.project (s);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
template<class V, class RS>
|
||||
BOOST_UBLAS_INLINE
|
||||
typename msvc_vproject_helper<V>::template return_type<RS>::type project (V &data, const RS &rs) {
|
||||
return msvc_vproject_helper<V>::apply (data, rs);
|
||||
}
|
||||
template<class V, class RS>
|
||||
BOOST_UBLAS_INLINE
|
||||
const typename msvc_vproject_helper<V>::template return_type<RS>::type project (const V &data, const RS &rs) {
|
||||
return msvc_vproject_helper<const V>::apply (data, rs);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Specialization of temporary_traits
|
||||
|
Loading…
Reference in New Issue
Block a user