forked from boostorg/tuple
Compare commits
8 Commits
svn-branch
...
sandbox-br
Author | SHA1 | Date | |
---|---|---|---|
e9e712e30f | |||
f904cd5d69 | |||
2b30eb2225 | |||
9fbc9b4cc6 | |||
9d64187c34 | |||
7b6203747a | |||
1b07c1a2d4 | |||
052b3db77f |
@ -37,6 +37,7 @@
|
||||
|
||||
#include "boost/type_traits/cv_traits.hpp"
|
||||
#include "boost/type_traits/function_traits.hpp"
|
||||
#include "boost/utility/swap.hpp"
|
||||
|
||||
#include "boost/detail/workaround.hpp" // needed for BOOST_WORKAROUND
|
||||
|
||||
@ -86,45 +87,28 @@ namespace detail {
|
||||
template<class T>
|
||||
class generate_error;
|
||||
|
||||
// - cons getters --------------------------------------------------------
|
||||
// called: get_class<N>::get<RETURN_TYPE>(aTuple)
|
||||
|
||||
template< int N >
|
||||
struct get_class {
|
||||
template<class RET, class HT, class TT >
|
||||
inline static RET get(const cons<HT, TT>& t)
|
||||
{
|
||||
#if BOOST_WORKAROUND(__IBMCPP__,==600)
|
||||
// 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<int N>
|
||||
struct drop_front {
|
||||
template<class Tuple>
|
||||
struct apply {
|
||||
typedef BOOST_DEDUCED_TYPENAME drop_front<N-1>::BOOST_NESTED_TEMPLATE
|
||||
apply<Tuple> next;
|
||||
typedef BOOST_DEDUCED_TYPENAME next::type::tail_type type;
|
||||
static const type& call(const Tuple& tup) {
|
||||
return next::call(tup).tail;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct get_class<0> {
|
||||
template<class RET, class HT, class TT>
|
||||
inline static RET get(const cons<HT, TT>& t)
|
||||
{
|
||||
return t.head;
|
||||
}
|
||||
template<class RET, class HT, class TT>
|
||||
inline static RET get(cons<HT, TT>& t)
|
||||
{
|
||||
return t.head;
|
||||
}
|
||||
struct drop_front<0> {
|
||||
template<class Tuple>
|
||||
struct apply {
|
||||
typedef Tuple type;
|
||||
static const type& call(const Tuple& tup) {
|
||||
return tup;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
} // end of namespace detail
|
||||
@ -140,41 +124,23 @@ struct get_class<0> {
|
||||
template<int N, class T>
|
||||
struct element
|
||||
{
|
||||
private:
|
||||
typedef typename T::tail_type Next;
|
||||
public:
|
||||
typedef typename element<N-1, Next>::type type;
|
||||
};
|
||||
template<class T>
|
||||
struct element<0,T>
|
||||
{
|
||||
typedef typename T::head_type type;
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||
apply<T>::type::head_type type;
|
||||
};
|
||||
|
||||
template<int N, class T>
|
||||
struct element<N, const T>
|
||||
{
|
||||
private:
|
||||
typedef typename T::tail_type Next;
|
||||
typedef typename element<N-1, Next>::type unqualified_type;
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||
apply<T>::type::head_type unqualified_type;
|
||||
public:
|
||||
#if BOOST_WORKAROUND(__BORLANDC__,<0x600)
|
||||
typedef const unqualified_type type;
|
||||
#else
|
||||
typedef 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;
|
||||
typedef BOOST_DEDUCED_TYPENAME boost::add_const<unqualified_type>::type type;
|
||||
#endif
|
||||
};
|
||||
|
||||
#else // def BOOST_NO_CV_SPECIALIZATIONS
|
||||
|
||||
namespace detail {
|
||||
@ -182,31 +148,16 @@ namespace detail {
|
||||
template<int N, class T, bool IsConst>
|
||||
struct element_impl
|
||||
{
|
||||
private:
|
||||
typedef typename T::tail_type Next;
|
||||
public:
|
||||
typedef typename element_impl<N-1, Next, IsConst>::type type;
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||
apply<T>::type::head_type type;
|
||||
};
|
||||
|
||||
template<int N, class T>
|
||||
struct element_impl<N, T, true /* IsConst */>
|
||||
{
|
||||
private:
|
||||
typedef typename T::tail_type Next;
|
||||
public:
|
||||
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;
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||
apply<T>::type::head_type unqualified_type;
|
||||
typedef const unqualified_type type;
|
||||
};
|
||||
|
||||
} // end of namespace detail
|
||||
@ -258,17 +209,10 @@ inline typename access_traits<
|
||||
typename element<N, cons<HT, TT> >::type
|
||||
>::non_const_type
|
||||
get(cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
||||
#if BOOST_WORKAROUND(__IBMCPP__,==600 )
|
||||
return detail::get_class<N>::
|
||||
#else
|
||||
return detail::get_class<N>::BOOST_NESTED_TEMPLATE
|
||||
#endif
|
||||
get<
|
||||
typename access_traits<
|
||||
typename element<N, cons<HT, TT> >::type
|
||||
>::non_const_type,
|
||||
HT,TT
|
||||
>(c);
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||
apply<cons<HT, TT> > impl;
|
||||
typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
|
||||
return const_cast<cons_element&>(impl::call(c)).head;
|
||||
}
|
||||
|
||||
// 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
|
||||
>::const_type
|
||||
get(const cons<HT, TT>& c BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(int, N)) {
|
||||
#if BOOST_WORKAROUND(__IBMCPP__,==600)
|
||||
return detail::get_class<N>::
|
||||
#else
|
||||
return detail::get_class<N>::BOOST_NESTED_TEMPLATE
|
||||
#endif
|
||||
get<
|
||||
typename access_traits<
|
||||
typename element<N, cons<HT, TT> >::type
|
||||
>::const_type,
|
||||
HT,TT
|
||||
>(c);
|
||||
typedef BOOST_DEDUCED_TYPENAME detail::drop_front<N>::BOOST_NESTED_TEMPLATE
|
||||
apply<cons<HT, TT> > impl;
|
||||
typedef BOOST_DEDUCED_TYPENAME impl::type cons_element;
|
||||
return impl::call(c).head;
|
||||
}
|
||||
|
||||
// -- the cons template --------------------------------------------------
|
||||
@ -663,18 +600,21 @@ public:
|
||||
// Swallows any assignment (by Doug Gregor)
|
||||
namespace detail {
|
||||
|
||||
struct swallow_assign;
|
||||
typedef void (detail::swallow_assign::*ignore_t)();
|
||||
struct swallow_assign {
|
||||
|
||||
swallow_assign(ignore_t(*)(ignore_t)) {}
|
||||
template<typename T>
|
||||
swallow_assign const& operator=(const T&) const {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// "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
|
||||
@ -756,6 +696,10 @@ struct make_tuple_traits<const reference_wrapper<T> >{
|
||||
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);
|
||||
}
|
||||
|
||||
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 -------------------------------------------------
|
||||
template<class T1>
|
||||
inline tuple<T1&> tie(T1& t1) {
|
||||
return tuple<T1&> (t1);
|
||||
template<class T0>
|
||||
inline typename detail::tie_mapper<T0>::type
|
||||
tie(T0& t0) {
|
||||
typedef typename detail::tie_mapper<T0>::type t;
|
||||
return t(t0);
|
||||
}
|
||||
|
||||
template<class T1, class T2>
|
||||
inline tuple<T1&, T2&> tie(T1& t1, T2& t2) {
|
||||
return tuple<T1&, T2&> (t1, t2);
|
||||
template<class T0, class T1>
|
||||
inline typename detail::tie_mapper<T0, T1>::type
|
||||
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>
|
||||
inline tuple<T1&, T2&, T3&> tie(T1& t1, T2& t2, T3& t3) {
|
||||
return tuple<T1&, T2&, T3&> (t1, t2, t3);
|
||||
template<class T0, class T1, class T2>
|
||||
inline typename detail::tie_mapper<T0, T1, T2>::type
|
||||
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>
|
||||
inline tuple<T1&, T2&, T3&, T4&> tie(T1& t1, T2& t2, T3& t3, T4& t4) {
|
||||
return tuple<T1&, T2&, T3&, T4&> (t1, t2, t3, t4);
|
||||
template<class T0, class T1, class T2, class T3>
|
||||
inline typename detail::tie_mapper<T0, T1, T2, T3>::type
|
||||
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>
|
||||
inline tuple<T1&, T2&, T3&, T4&, T5&>
|
||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5) {
|
||||
return tuple<T1&, T2&, T3&, T4&, T5&> (t1, t2, t3, t4, t5);
|
||||
template<class T0, class T1, class T2, class T3, class T4>
|
||||
inline typename detail::tie_mapper<T0, T1, T2, T3, T4>::type
|
||||
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||
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>
|
||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&>
|
||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6) {
|
||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&> (t1, t2, t3, t4, t5, t6);
|
||||
template<class T0, class T1, class T2, class T3, class T4, class T5>
|
||||
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5>::type
|
||||
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||
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>
|
||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&>
|
||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7) {
|
||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&> (t1, t2, t3, t4, t5, t6, t7);
|
||||
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6>
|
||||
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6>::type
|
||||
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||
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,
|
||||
class T8>
|
||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&>
|
||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8) {
|
||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&>
|
||||
(t1, t2, t3, t4, t5, t6, t7, t8);
|
||||
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
||||
class T7>
|
||||
inline typename detail::tie_mapper<T0, T1, T2, T3, T4, T5, T6, T7>::type
|
||||
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||
T4& t4, T5& t5, T6& t6, T7& t7) {
|
||||
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,
|
||||
class T8, class T9>
|
||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&>
|
||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8,
|
||||
T9& t9) {
|
||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&>
|
||||
(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>
|
||||
inline typename detail::tie_mapper
|
||||
<T0, T1, T2, T3, T4, T5, T6, T7, T8>::type
|
||||
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||
T4& t4, T5& t5, T6& t6, T7& t7,
|
||||
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,
|
||||
class T8, class T9, class T10>
|
||||
inline tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&, T10&>
|
||||
tie(T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8,
|
||||
T9& t9, T10& t10) {
|
||||
return tuple<T1&, T2&, T3&, T4&, T5&, T6&, T7&, T8&, T9&, T10&>
|
||||
(t1, t2, t3, t4, t5, t6, t7, t8, t9, t10);
|
||||
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6,
|
||||
class T7, class T8, class T9>
|
||||
inline typename detail::tie_mapper
|
||||
<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::type
|
||||
tie(T0& t0, T1& t1, T2& t2, T3& t3,
|
||||
T4& t4, T5& t5, T6& t6, T7& t7,
|
||||
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
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP
|
||||
|
||||
#include "boost/type_traits.hpp"
|
||||
#include "boost/utility/swap.hpp"
|
||||
#include <utility>
|
||||
|
||||
#if defined BOOST_MSVC
|
||||
@ -836,6 +837,29 @@ namespace tuples {
|
||||
|
||||
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 boost
|
||||
#endif // BOOST_TUPLE_BASIC_NO_PARTIAL_SPEC_HPP
|
||||
|
@ -29,6 +29,8 @@
|
||||
#include <ostream>
|
||||
#endif
|
||||
|
||||
#include <sstream>
|
||||
|
||||
#include "boost/tuple/tuple.hpp"
|
||||
|
||||
// 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
|
||||
@ -280,6 +298,23 @@ print(std::basic_ostream<CharType, CharTrait>& o, const cons<T1, T2>& t) {
|
||||
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
|
||||
|
||||
} // 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) {
|
||||
if (!o.good() ) return o;
|
||||
if (detail::handle_width(o, t)) return o;
|
||||
|
||||
const char l =
|
||||
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>
|
||||
inline std::ostream& operator<<(std::ostream& o, const cons<T1, T2>& t) {
|
||||
if (!o.good() ) return o;
|
||||
if (detail::handle_width(o, t)) return o;
|
||||
|
||||
const char l =
|
||||
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,
|
||||
const null_type& t) {
|
||||
if (!o.good() ) return o;
|
||||
if (detail::handle_width(o, t)) return o;
|
||||
|
||||
const CharType l =
|
||||
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,
|
||||
const cons<T1, T2>& t) {
|
||||
if (!o.good() ) return o;
|
||||
if (detail::handle_width(o, t)) return o;
|
||||
|
||||
const CharType l =
|
||||
detail::format_info::get_manipulator(o, detail::format_info::open);
|
||||
@ -384,6 +423,8 @@ extract_and_check_delimiter(
|
||||
if (is.good() && c!=d) {
|
||||
is.setstate(std::ios::failbit);
|
||||
}
|
||||
} else {
|
||||
is >> std::ws;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
@ -478,6 +519,8 @@ extract_and_check_delimiter(
|
||||
if (is.good() && c!=d) {
|
||||
is.setstate(std::ios::failbit);
|
||||
}
|
||||
} else {
|
||||
is >> std::ws;
|
||||
}
|
||||
return is;
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
|
||||
#if defined BOOST_NO_STRINGSTREAM
|
||||
#include <strstream>
|
||||
@ -77,6 +78,11 @@ int test_main(int argc, char * argv[] ) {
|
||||
os3 << set_close(']');
|
||||
os3 << make_tuple();
|
||||
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");
|
||||
|
||||
@ -120,6 +126,13 @@ int test_main(int argc, char * argv[] ) {
|
||||
is3 >> set_close(']');
|
||||
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:
|
||||
// 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
|
||||
|
@ -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();
|
||||
const_tuple_test();
|
||||
tuple_length_test();
|
||||
tuple_swap_test();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user