mirror of
https://github.com/boostorg/tuple.git
synced 2025-07-30 20:57:15 +02:00
Reimplement boost::tuples::element and boost::tuples::get to make better use of memoization. Fixes #2130
[SVN r62683]
This commit is contained in:
@ -86,45 +86,28 @@ namespace detail {
|
|||||||
template<class T>
|
template<class T>
|
||||||
class generate_error;
|
class generate_error;
|
||||||
|
|
||||||
// - cons getters --------------------------------------------------------
|
template<int N>
|
||||||
// called: get_class<N>::get<RETURN_TYPE>(aTuple)
|
struct drop_front {
|
||||||
|
template<class Tuple>
|
||||||
template< int N >
|
struct apply {
|
||||||
struct get_class {
|
typedef BOOST_DEDUCED_TYPENAME drop_front<N-1>::BOOST_NESTED_TEMPLATE
|
||||||
template<class RET, class HT, class TT >
|
apply<Tuple> next;
|
||||||
inline static RET get(const cons<HT, TT>& t)
|
typedef BOOST_DEDUCED_TYPENAME next::type::tail_type type;
|
||||||
{
|
static const type& call(const Tuple& tup) {
|
||||||
#if BOOST_WORKAROUND(__IBMCPP__,==600)
|
return next::call(tup).tail;
|
||||||
// vacpp 6.0 is not very consistent regarding the member template keyword
|
|
||||||
// Here it generates an error when the template keyword is used.
|
|
||||||
return get_class<N-1>::get<RET>(t.tail);
|
|
||||||
#else
|
|
||||||
return get_class<N-1>::BOOST_NESTED_TEMPLATE get<RET>(t.tail);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
template<class RET, class HT, class TT >
|
|
||||||
inline static RET get(cons<HT, TT>& t)
|
|
||||||
{
|
|
||||||
#if BOOST_WORKAROUND(__IBMCPP__,==600)
|
|
||||||
return get_class<N-1>::get<RET>(t.tail);
|
|
||||||
#else
|
|
||||||
return get_class<N-1>::BOOST_NESTED_TEMPLATE get<RET>(t.tail);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
struct get_class<0> {
|
struct drop_front<0> {
|
||||||
template<class RET, class HT, class TT>
|
template<class Tuple>
|
||||||
inline static RET get(const cons<HT, TT>& t)
|
struct apply {
|
||||||
{
|
typedef Tuple type;
|
||||||
return t.head;
|
static const type& call(const Tuple& tup) {
|
||||||
}
|
return tup;
|
||||||
template<class RET, class HT, class TT>
|
|
||||||
inline static RET get(cons<HT, TT>& t)
|
|
||||||
{
|
|
||||||
return t.head;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace detail
|
} // end of namespace detail
|
||||||
@ -140,41 +123,23 @@ struct get_class<0> {
|
|||||||
template<int N, class T>
|
template<int N, class T>
|
||||||
struct element
|
struct element
|
||||||
{
|
{
|
||||||
private:
|
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||||
typedef typename T::tail_type Next;
|
apply<T>::type::head_type type;
|
||||||
public:
|
|
||||||
typedef typename element<N-1, Next>::type type;
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct element<0,T>
|
|
||||||
{
|
|
||||||
typedef typename T::head_type type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N, class T>
|
template<int N, class T>
|
||||||
struct element<N, const T>
|
struct element<N, const T>
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
typedef typename T::tail_type Next;
|
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||||
typedef typename element<N-1, Next>::type unqualified_type;
|
apply<T>::type::head_type unqualified_type;
|
||||||
public:
|
public:
|
||||||
#if BOOST_WORKAROUND(__BORLANDC__,<0x600)
|
#if BOOST_WORKAROUND(__BORLANDC__,<0x600)
|
||||||
typedef const unqualified_type type;
|
typedef const unqualified_type type;
|
||||||
#else
|
#else
|
||||||
typedef typename boost::add_const<unqualified_type>::type type;
|
typedef BOOST_DEDUCED_TYPENAME boost::add_const<unqualified_type>::type type;
|
||||||
#endif
|
|
||||||
|
|
||||||
};
|
|
||||||
template<class T>
|
|
||||||
struct element<0,const T>
|
|
||||||
{
|
|
||||||
#if BOOST_WORKAROUND(__BORLANDC__,<0x600)
|
|
||||||
typedef const typename T::head_type type;
|
|
||||||
#else
|
|
||||||
typedef typename boost::add_const<typename T::head_type>::type type;
|
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#else // def BOOST_NO_CV_SPECIALIZATIONS
|
#else // def BOOST_NO_CV_SPECIALIZATIONS
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
@ -182,31 +147,16 @@ namespace detail {
|
|||||||
template<int N, class T, bool IsConst>
|
template<int N, class T, bool IsConst>
|
||||||
struct element_impl
|
struct element_impl
|
||||||
{
|
{
|
||||||
private:
|
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||||
typedef typename T::tail_type Next;
|
apply<T>::type::head_type type;
|
||||||
public:
|
|
||||||
typedef typename element_impl<N-1, Next, IsConst>::type type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template<int N, class T>
|
template<int N, class T>
|
||||||
struct element_impl<N, T, true /* IsConst */>
|
struct element_impl<N, T, true /* IsConst */>
|
||||||
{
|
{
|
||||||
private:
|
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||||
typedef typename T::tail_type Next;
|
apply<T>::type::head_type unqualified_type;
|
||||||
public:
|
typedef const unqualified_type type;
|
||||||
typedef const typename element_impl<N-1, Next, true>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct element_impl<0, T, false /* IsConst */>
|
|
||||||
{
|
|
||||||
typedef typename T::head_type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class T>
|
|
||||||
struct element_impl<0, T, true /* IsConst */>
|
|
||||||
{
|
|
||||||
typedef const typename T::head_type type;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace detail
|
} // end of namespace detail
|
||||||
@ -258,17 +208,10 @@ inline typename access_traits<
|
|||||||
typename element<N, cons<HT, TT> >::type
|
typename element<N, cons<HT, TT> >::type
|
||||||
>::non_const_type
|
>::non_const_type
|
||||||
get(cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
get(cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
||||||
#if BOOST_WORKAROUND(__IBMCPP__,==600 )
|
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||||
return detail::get_class<N>::
|
apply<cons<HT, TT> > impl;
|
||||||
#else
|
typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
|
||||||
return detail::get_class<N>::BOOST_NESTED_TEMPLATE
|
return const_cast<cons_element&>(impl::call(c)).head;
|
||||||
#endif
|
|
||||||
get<
|
|
||||||
typename access_traits<
|
|
||||||
typename element<N, cons<HT, TT> >::type
|
|
||||||
>::non_const_type,
|
|
||||||
HT,TT
|
|
||||||
>(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// get function for const cons-lists, returns a const reference to
|
// get function for const cons-lists, returns a const reference to
|
||||||
@ -279,17 +222,10 @@ inline typename access_traits<
|
|||||||
typename element<N, cons<HT, TT> >::type
|
typename element<N, cons<HT, TT> >::type
|
||||||
>::const_type
|
>::const_type
|
||||||
get(const cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
get(const cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
||||||
#if BOOST_WORKAROUND(__IBMCPP__,==600)
|
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||||
return detail::get_class<N>::
|
apply<cons<HT, TT> > impl;
|
||||||
#else
|
typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
|
||||||
return detail::get_class<N>::BOOST_NESTED_TEMPLATE
|
return impl::call(c).head;
|
||||||
#endif
|
|
||||||
get<
|
|
||||||
typename access_traits<
|
|
||||||
typename element<N, cons<HT, TT> >::type
|
|
||||||
>::const_type,
|
|
||||||
HT,TT
|
|
||||||
>(c);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -- the cons template --------------------------------------------------
|
// -- the cons template --------------------------------------------------
|
||||||
|
Reference in New Issue
Block a user