forked from boostorg/tuple
Compare commits
8 Commits
svn-branch
...
svn-branch
Author | SHA1 | Date | |
---|---|---|---|
f6be1722f0 | |||
f904cd5d69 | |||
2b30eb2225 | |||
9fbc9b4cc6 | |||
9d64187c34 | |||
7b6203747a | |||
1b07c1a2d4 | |||
052b3db77f |
@ -37,6 +37,7 @@
|
|||||||
|
|
||||||
#include "boost/type_traits/cv_traits.hpp"
|
#include "boost/type_traits/cv_traits.hpp"
|
||||||
#include "boost/type_traits/function_traits.hpp"
|
#include "boost/type_traits/function_traits.hpp"
|
||||||
|
#include "boost/utility/swap.hpp"
|
||||||
|
|
||||||
#include "boost/detail/workaround.hpp" // needed for BOOST_WORKAROUND
|
#include "boost/detail/workaround.hpp" // needed for BOOST_WORKAROUND
|
||||||
|
|
||||||
@ -86,45 +87,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 +124,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 +148,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 +209,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 +223,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 --------------------------------------------------
|
||||||
@ -663,18 +600,21 @@ public:
|
|||||||
// Swallows any assignment (by Doug Gregor)
|
// Swallows any assignment (by Doug Gregor)
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
struct swallow_assign;
|
||||||
|
typedef void (detail::swallow_assign::*ignore_t)();
|
||||||
struct swallow_assign {
|
struct swallow_assign {
|
||||||
|
swallow_assign(ignore_t(*)(ignore_t)) {}
|
||||||
template<typename T>
|
template<typename T>
|
||||||
swallow_assign const& operator=(const T&) const {
|
swallow_assign const& operator=(const T&) const {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
// "ignore" allows tuple positions to be ignored when using "tie".
|
// "ignore" allows tuple positions to be ignored when using "tie".
|
||||||
detail::swallow_assign const ignore = detail::swallow_assign();
|
inline detail::ignore_t ignore(detail::ignore_t) { return 0; }
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// The call_traits for make_tuple
|
// The call_traits for make_tuple
|
||||||
@ -756,6 +696,10 @@ struct make_tuple_traits<const reference_wrapper<T> >{
|
|||||||
typedef T& type;
|
typedef T& type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct make_tuple_traits<detail::ignore_t(detail::ignore_t)> {
|
||||||
|
typedef detail::swallow_assign type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -877,71 +821,154 @@ make_tuple(const T0& t0, const T1& t1, const T2& t2, const T3& t3,
|
|||||||
return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
|
return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct tie_traits {
|
||||||
|
typedef T& type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct tie_traits<ignore_t(ignore_t)> {
|
||||||
|
typedef swallow_assign type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct tie_traits<void> {
|
||||||
|
typedef null_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <
|
||||||
|
class T0 = void, class T1 = void, class T2 = void,
|
||||||
|
class T3 = void, class T4 = void, class T5 = void,
|
||||||
|
class T6 = void, class T7 = void, class T8 = void,
|
||||||
|
class T9 = void
|
||||||
|
>
|
||||||
|
struct tie_mapper {
|
||||||
|
typedef
|
||||||
|
tuple<typename tie_traits<T0>::type,
|
||||||
|
typename tie_traits<T1>::type,
|
||||||
|
typename tie_traits<T2>::type,
|
||||||
|
typename tie_traits<T3>::type,
|
||||||
|
typename tie_traits<T4>::type,
|
||||||
|
typename tie_traits<T5>::type,
|
||||||
|
typename tie_traits<T6>::type,
|
||||||
|
typename tie_traits<T7>::type,
|
||||||
|
typename tie_traits<T8>::type,
|
||||||
|
typename tie_traits<T9>::type> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Tie function templates -------------------------------------------------
|
// Tie function templates -------------------------------------------------
|
||||||
template<class T1>
|
template<class T0>
|
||||||
inline tuple<T1&> tie(T1& t1) {
|
inline typename detail::tie_mapper<T0>::type
|
||||||
return tuple<T1&> (t1);
|
tie(T0& t0) {
|
||||||
|
typedef typename detail::tie_mapper<T0>::type t;
|
||||||
|
return t(t0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2>
|
template<class T0, class T1>
|
||||||
inline tuple<T1&, T2&> tie(T1& t1, T2& t2) {
|
inline typename detail::tie_mapper<T0, T1>::type
|
||||||
return tuple<T1&, T2&> (t1, t2);
|
tie(T0& t0, T1& t1) {
|
||||||
|
typedef typename detail::tie_mapper<T0, T1>::type t;
|
||||||
|
return t(t0, t1);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2, class T3>
|
template<class T0, class T1, class T2>
|
||||||
inline tuple<T1&, T2&, T3&> tie(T1& t1, T2& t2, T3& t3) {
|
inline typename detail::tie_mapper<T0, T1, T2>::type
|
||||||
return tuple<T1&, T2&, T3&> (t1, t2, t3);
|
tie(T0& t0, T1& t1, T2& t2) {
|
||||||
|
typedef typename detail::tie_mapper<T0, T1, T2>::type t;
|
||||||
|
return t(t0, t1, t2);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2, class T3, class T4>
|
template<class T0, class T1, class T2, class T3>
|
||||||
inline tuple<T1&, T2&, T3&, T4&> tie(T1& t1, T2& t2, T3& t3, T4& t4) {
|
inline typename detail::tie_mapper<T0, T1, T2, T3>::type
|
||||||
return tuple<T1&, T2&, T3&, T4&> (t1, t2, t3, t4);
|
tie(T0& t0, T1& t1, T2& t2, T3& t3) {
|
||||||
|
typedef typename detail::tie_mapper<T0, T1, T2, T3>::type t;
|
||||||
|
return t(t0, t1, t2, t3);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2, class T3, class T4, class T5>
|
template<class T0, class T1, class T2, class T3, class T4>
|
||||||
inline tuple<T1&, T2&, T3&, T4&, T5&>
|
inline typename detail::tie_mapper<T0, T1, T2, T3, T4>::type
|
||||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) {
|
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||||
return tuple<T1&, T2&, T3&, T4&, T5&> (t1, t2, t3, t4, t5);
|
T4& t4) {
|
||||||
|
typedef typename detail::tie_mapper<T0, T1, T2, T3, T4>::type t;
|
||||||
|
return t(t0, t1, t2, t3, t4);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2, class T3, class T4, class T5, class T6>
|
template<class T0, class T1, class T2, class T3, class T4, class T5>
|
||||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&>
|
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type
|
||||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) {
|
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&> (t1, t2, t3, t4, t5, t6);
|
T4& t4, T5& t5) {
|
||||||
|
typedef typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type t;
|
||||||
|
return t(t0, t1, t2, t3, t4, t5);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7>
|
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
|
||||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&>
|
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6>::type
|
||||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7) {
|
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&> (t1, t2, t3, t4, t5, t6, t7);
|
T4& t4, T5& t5, T6& t6) {
|
||||||
|
typedef typename detail::tie_mapper
|
||||||
|
<T0, T1, T2, T3, T4, T5, T6>::type t;
|
||||||
|
return t(t0, t1, t2, t3, t4, t5, t6);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
|
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
||||||
class T8>
|
class T7>
|
||||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&>
|
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
|
||||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8) {
|
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&>
|
T4& t4, T5& t5, T6& t6, T7& t7) {
|
||||||
(t1, t2, t3, t4, t5, t6, t7, t8);
|
typedef typename detail::tie_mapper
|
||||||
|
<T0, T1, T2, T3, T4, T5, T6, T7>::type t;
|
||||||
|
return t(t0, t1, t2, t3, t4, t5, t6, t7);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
|
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
||||||
class T8, class T9>
|
class T7, class T8>
|
||||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&>
|
inline typename detail::tie_mapper
|
||||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8,
|
<T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
|
||||||
T9& t9) {
|
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&>
|
T4& t4, T5& t5, T6& t6, T7& t7,
|
||||||
(t1, t2, t3, t4, t5, t6, t7, t8, t9);
|
T8& t8) {
|
||||||
|
typedef typename detail::tie_mapper
|
||||||
|
<T0, T1, T2, T3, T4, T5, T6, T7, T8>::type t;
|
||||||
|
return t(t0, t1, t2, t3, t4, t5, t6, t7, t8);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T1, class T2, class T3, class T4, class T5, class T6, class T7,
|
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
||||||
class T8, class T9, class T10>
|
class T7, class T8, class T9>
|
||||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&, T10&>
|
inline typename detail::tie_mapper
|
||||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8,
|
<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
|
||||||
T9& t9, T10& t10) {
|
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&, T10&>
|
T4& t4, T5& t5, T6& t6, T7& t7,
|
||||||
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
|
T8& t8, T9& t9) {
|
||||||
|
typedef typename detail::tie_mapper
|
||||||
|
<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type t;
|
||||||
|
return t(t0, t1, t2, t3, t4, t5, t6, t7, t8, t9);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T0, class T1, class T2, class T3, class T4,
|
||||||
|
class T5, class T6, class T7, class T8, class T9>
|
||||||
|
void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
|
||||||
|
tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
|
||||||
|
inline void swap(null_type&, null_type&) {}
|
||||||
|
template<class HH>
|
||||||
|
inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
|
||||||
|
::boost::swap(lhs.head, rhs.head);
|
||||||
|
}
|
||||||
|
template<class HH, class TT>
|
||||||
|
inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
|
||||||
|
::boost::swap(lhs.head, rhs.head);
|
||||||
|
::boost::tuples::swap(lhs.tail, rhs.tail);
|
||||||
|
}
|
||||||
|
template <class T0, class T1, class T2, class T3, class T4,
|
||||||
|
class T5, class T6, class T7, class T8, class T9>
|
||||||
|
inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
|
||||||
|
tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
|
||||||
|
typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
|
||||||
|
typedef typename tuple_type::inherited base;
|
||||||
|
::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace tuples
|
} // end of namespace tuples
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#define BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP
|
#define BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP
|
||||||
|
|
||||||
#include "boost/type_traits.hpp"
|
#include "boost/type_traits.hpp"
|
||||||
|
#include "boost/utility/swap.hpp"
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#if defined BOOST_MSVC
|
#if defined BOOST_MSVC
|
||||||
@ -836,6 +837,29 @@ namespace tuples {
|
|||||||
|
|
||||||
detail::swallow_assign const ignore = detail::swallow_assign();
|
detail::swallow_assign const ignore = detail::swallow_assign();
|
||||||
|
|
||||||
|
template <class T0, class T1, class T2, class T3, class T4,
|
||||||
|
class T5, class T6, class T7, class T8, class T9>
|
||||||
|
void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
|
||||||
|
tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs);
|
||||||
|
inline void swap(null_type&, null_type&) {}
|
||||||
|
template<class HH>
|
||||||
|
inline void swap(cons<HH, null_type>& lhs, cons<HH, null_type>& rhs) {
|
||||||
|
::boost::swap(lhs.head, rhs.head);
|
||||||
|
}
|
||||||
|
template<class HH, class TT>
|
||||||
|
inline void swap(cons<HH, TT>& lhs, cons<HH, TT>& rhs) {
|
||||||
|
::boost::swap(lhs.head, rhs.head);
|
||||||
|
::boost::tuples::swap(lhs.tail, rhs.tail);
|
||||||
|
}
|
||||||
|
template <class T0, class T1, class T2, class T3, class T4,
|
||||||
|
class T5, class T6, class T7, class T8, class T9>
|
||||||
|
inline void swap(tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& lhs,
|
||||||
|
tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>& rhs) {
|
||||||
|
typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> tuple_type;
|
||||||
|
typedef typename tuple_type::inherited base;
|
||||||
|
::boost::tuples::swap(static_cast<base&>(lhs), static_cast<base&>(rhs));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace tuples
|
} // namespace tuples
|
||||||
} // namespace boost
|
} // namespace boost
|
||||||
#endif // BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP
|
#endif // BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include <ostream>
|
#include <ostream>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "boost/tuple/tuple.hpp"
|
#include "boost/tuple/tuple.hpp"
|
||||||
|
|
||||||
// This is ugly: one should be using twoargument isspace since whitspace can
|
// This is ugly: one should be using twoargument isspace since whitspace can
|
||||||
@ -244,6 +246,22 @@ print(std::ostream& o, const cons<T1, T2>& t) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline bool handle_width(std::ostream& o, const T& t) {
|
||||||
|
std::streamsize width = o.width();
|
||||||
|
if(width == 0) return false;
|
||||||
|
|
||||||
|
std::ostringstream ss;
|
||||||
|
|
||||||
|
ss.copyfmt(o);
|
||||||
|
ss.tie(0);
|
||||||
|
ss.width(0);
|
||||||
|
|
||||||
|
ss << t;
|
||||||
|
o << ss.str();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -280,6 +298,23 @@ print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, T2>& t) {
|
|||||||
return print(o, t.tail);
|
return print(o, t.tail);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class CharT, class Traits, class T>
|
||||||
|
inline bool handle_width(std::basic_ostream<CharT, Traits>& o, const T& t) {
|
||||||
|
std::streamsize width = o.width();
|
||||||
|
if(width == 0) return false;
|
||||||
|
|
||||||
|
std::basic_ostringstream<CharT, Traits> ss;
|
||||||
|
|
||||||
|
ss.copyfmt(o);
|
||||||
|
ss.tie(0);
|
||||||
|
ss.width(0);
|
||||||
|
|
||||||
|
ss << t;
|
||||||
|
o << ss.str();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // BOOST_NO_TEMPLATED_STREAMS
|
#endif // BOOST_NO_TEMPLATED_STREAMS
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
@ -288,6 +323,7 @@ print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, T2>& t) {
|
|||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& o, const null_type& t) {
|
inline std::ostream& operator<<(std::ostream& o, const null_type& t) {
|
||||||
if (!o.good() ) return o;
|
if (!o.good() ) return o;
|
||||||
|
if (detail::handle_width(o, t)) return o;
|
||||||
|
|
||||||
const char l =
|
const char l =
|
||||||
detail::format_info::get_manipulator(o, detail::format_info::open);
|
detail::format_info::get_manipulator(o, detail::format_info::open);
|
||||||
@ -303,6 +339,7 @@ inline std::ostream& operator<<(std::ostream& o, const null_type& t) {
|
|||||||
template<class T1, class T2>
|
template<class T1, class T2>
|
||||||
inline std::ostream& operator<<(std::ostream& o, const cons<T1, T2>& t) {
|
inline std::ostream& operator<<(std::ostream& o, const cons<T1, T2>& t) {
|
||||||
if (!o.good() ) return o;
|
if (!o.good() ) return o;
|
||||||
|
if (detail::handle_width(o, t)) return o;
|
||||||
|
|
||||||
const char l =
|
const char l =
|
||||||
detail::format_info::get_manipulator(o, detail::format_info::open);
|
detail::format_info::get_manipulator(o, detail::format_info::open);
|
||||||
@ -325,6 +362,7 @@ inline std::basic_ostream<CharType, CharTrait>&
|
|||||||
operator<<(std::basic_ostream<CharType, CharTrait>& o,
|
operator<<(std::basic_ostream<CharType, CharTrait>& o,
|
||||||
const null_type& t) {
|
const null_type& t) {
|
||||||
if (!o.good() ) return o;
|
if (!o.good() ) return o;
|
||||||
|
if (detail::handle_width(o, t)) return o;
|
||||||
|
|
||||||
const CharType l =
|
const CharType l =
|
||||||
detail::format_info::get_manipulator(o, detail::format_info::open);
|
detail::format_info::get_manipulator(o, detail::format_info::open);
|
||||||
@ -342,6 +380,7 @@ inline std::basic_ostream<CharType, CharTrait>&
|
|||||||
operator<<(std::basic_ostream<CharType, CharTrait>& o,
|
operator<<(std::basic_ostream<CharType, CharTrait>& o,
|
||||||
const cons<T1, T2>& t) {
|
const cons<T1, T2>& t) {
|
||||||
if (!o.good() ) return o;
|
if (!o.good() ) return o;
|
||||||
|
if (detail::handle_width(o, t)) return o;
|
||||||
|
|
||||||
const CharType l =
|
const CharType l =
|
||||||
detail::format_info::get_manipulator(o, detail::format_info::open);
|
detail::format_info::get_manipulator(o, detail::format_info::open);
|
||||||
@ -384,6 +423,8 @@ extract_and_check_delimiter(
|
|||||||
if (is.good() && c!=d) {
|
if (is.good() && c!=d) {
|
||||||
is.setstate(std::ios::failbit);
|
is.setstate(std::ios::failbit);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
is >> std::ws;
|
||||||
}
|
}
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
@ -478,6 +519,8 @@ extract_and_check_delimiter(
|
|||||||
if (is.good() && c!=d) {
|
if (is.good() && c!=d) {
|
||||||
is.setstate(std::ios::failbit);
|
is.setstate(std::ios::failbit);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
is >> std::ws;
|
||||||
}
|
}
|
||||||
return is;
|
return is;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iomanip>
|
||||||
|
|
||||||
#if defined BOOST_NO_STRINGSTREAM
|
#if defined BOOST_NO_STRINGSTREAM
|
||||||
#include <strstream>
|
#include <strstream>
|
||||||
@ -77,6 +78,11 @@ int test_main(int argc, char * argv[] ) {
|
|||||||
os3 << set_close(']');
|
os3 << set_close(']');
|
||||||
os3 << make_tuple();
|
os3 << make_tuple();
|
||||||
BOOST_CHECK (os3.str() == std::string("()[]") );
|
BOOST_CHECK (os3.str() == std::string("()[]") );
|
||||||
|
|
||||||
|
// check width
|
||||||
|
useThisOStringStream os4;
|
||||||
|
os4 << std::setw(10) << make_tuple(1, 2, 3);
|
||||||
|
BOOST_CHECK (os4.str() == std::string(" (1 2 3)") );
|
||||||
|
|
||||||
std::ofstream tmp("temp.tmp");
|
std::ofstream tmp("temp.tmp");
|
||||||
|
|
||||||
@ -120,6 +126,13 @@ int test_main(int argc, char * argv[] ) {
|
|||||||
is3 >> set_close(']');
|
is3 >> set_close(']');
|
||||||
BOOST_CHECK(bool(is3 >> ti2));
|
BOOST_CHECK(bool(is3 >> ti2));
|
||||||
|
|
||||||
|
// Make sure that whitespace between elements
|
||||||
|
// is skipped.
|
||||||
|
useThisIStringStream is4("(100 200 300)");
|
||||||
|
|
||||||
|
BOOST_CHECK(bool(is4 >> std::noskipws >> ti1));
|
||||||
|
BOOST_CHECK(ti1 == make_tuple(100, 200, 300));
|
||||||
|
|
||||||
// Note that strings are problematic:
|
// Note that strings are problematic:
|
||||||
// writing a tuple on a stream and reading it back doesn't work in
|
// writing a tuple on a stream and reading it back doesn't work in
|
||||||
// general. If this is wanted, some kind of a parseable string class
|
// general. If this is wanted, some kind of a parseable string class
|
||||||
|
@ -445,6 +445,26 @@ void tuple_length_test()
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// - testing swap -----------------------------------------------------------
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
void tuple_swap_test()
|
||||||
|
{
|
||||||
|
tuple<int, float, double> t1(1, 2.0f, 3.0), t2(4, 5.0f, 6.0);
|
||||||
|
swap(t1, t2);
|
||||||
|
BOOST_CHECK(get<0>(t1) == 4);
|
||||||
|
BOOST_CHECK(get<1>(t1) == 5.0f);
|
||||||
|
BOOST_CHECK(get<2>(t1) == 6.0);
|
||||||
|
BOOST_CHECK(get<0>(t2) == 1);
|
||||||
|
BOOST_CHECK(get<1>(t2) == 2.0f);
|
||||||
|
BOOST_CHECK(get<2>(t2) == 3.0);
|
||||||
|
|
||||||
|
int i = 1,j = 2;
|
||||||
|
boost::tuple<int&> t3(i), t4(j);
|
||||||
|
swap(t3, t4);
|
||||||
|
BOOST_CHECK(i == 2);
|
||||||
|
BOOST_CHECK(j == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -465,6 +485,7 @@ int test_main(int, char *[]) {
|
|||||||
cons_test();
|
cons_test();
|
||||||
const_tuple_test();
|
const_tuple_test();
|
||||||
tuple_length_test();
|
tuple_length_test();
|
||||||
|
tuple_swap_test();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user