support for boost::tuples

[SVN r35350]
This commit is contained in:
Joel de Guzman
2006-09-27 00:42:32 +00:00
parent 798c527173
commit 3f27fbe969
24 changed files with 645 additions and 4 deletions

View File

@ -9,6 +9,7 @@
#if !defined(BOOST_FUSION_ADAPTED_30122005_1420)
#define BOOST_FUSION_ADAPTED_30122005_1420
#include <boost/fusion/sequence/adapted/boost_tuple.hpp>
#include <boost/fusion/sequence/adapted/std_pair.hpp>
#include <boost/fusion/sequence/adapted/array.hpp>
#include <boost/fusion/sequence/adapted/mpl.hpp>

View File

@ -0,0 +1,21 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_BOOST_TUPLE_09272006_0732)
#define BOOST_FUSION_BOOST_TUPLE_09272006_0732
#include <boost/fusion/sequence/adapted/boost_tuple/tag_of.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple/detail/is_view_impl.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple/detail/is_sequence_impl.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple/detail/category_of_impl.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple/detail/begin_impl.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple/detail/end_impl.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple/detail/size_impl.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple/detail/at_impl.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple/detail/value_at_impl.hpp>
#endif

View File

@ -0,0 +1,113 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(FUSION_BOOST_TUPLE_ITERATOR_09262006_1851)
#define FUSION_BOOST_TUPLE_ITERATOR_09262006_1851
#include <boost/fusion/iterator/iterator_facade.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/tuple/tuple.hpp>
namespace boost { namespace fusion
{
struct forward_traversal_tag;
template <typename Cons = tuples::null_type>
struct boost_tuple_iterator
: iterator_facade<boost_tuple_iterator<Cons>, forward_traversal_tag>
{
typedef Cons cons_type;
explicit boost_tuple_iterator(Cons& cons)
: cons(cons) {}
Cons& cons;
template <typename Iterator>
struct value_of : mpl::identity<typename Iterator::cons_type::head_type> {};
template <typename Iterator>
struct deref
{
typedef typename value_of<Iterator>::type element;
typedef typename
mpl::if_<
is_const<typename Iterator::cons_type>
, typename tuples::access_traits<element>::const_type
, typename tuples::access_traits<element>::non_const_type
>::type
type;
static type
call(Iterator const& iter)
{
return iter.cons.get_head();
}
};
template <typename Iterator>
struct next
{
typedef typename Iterator::cons_type cons_type;
typedef typename cons_type::tail_type tail_type;
typedef boost_tuple_iterator<
typename mpl::eval_if<
is_const<cons_type>
, add_const<tail_type>
, mpl::identity<tail_type>
>::type>
type;
static type
call(Iterator const& iter)
{
return type(iter.cons.get_tail());
}
};
};
template <>
struct boost_tuple_iterator<tuples::null_type>
: iterator_facade<boost_tuple_iterator<tuples::null_type>, forward_traversal_tag>
{
template <typename Cons>
explicit boost_tuple_iterator(Cons const&) {}
};
template <>
struct boost_tuple_iterator<tuples::null_type const>
: iterator_facade<boost_tuple_iterator<tuples::null_type const>, forward_traversal_tag>
{
template <typename Cons>
explicit boost_tuple_iterator(Cons const&) {}
};
template <>
struct boost_tuple_iterator<tuples::tuple<> >
: iterator_facade<boost_tuple_iterator<tuples::tuple<> >, forward_traversal_tag>
{
template <typename Cons>
explicit boost_tuple_iterator(Cons const&) {}
};
template <>
struct boost_tuple_iterator<tuples::tuple<> const>
: iterator_facade<boost_tuple_iterator<tuples::tuple<> const>, forward_traversal_tag>
{
template <typename Cons>
explicit boost_tuple_iterator(Cons const&) {}
};
}}
#endif

View File

@ -0,0 +1,51 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_AT_IMPL_09262006_1920)
#define BOOST_FUSION_AT_IMPL_09262006_1920
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/if.hpp>
namespace boost { namespace fusion
{
struct boost_tuple_tag;
namespace extension
{
template<typename T>
struct at_impl;
template <>
struct at_impl<boost_tuple_tag>
{
template <typename Sequence, typename N>
struct apply
{
typedef typename
tuples::element<N::value, Sequence>::type
element;
typedef typename
mpl::if_<
is_const<Sequence>
, typename tuples::access_traits<element>::const_type
, typename tuples::access_traits<element>::non_const_type
>::type
type;
static type
call(Sequence& seq)
{
return tuples::get<N::value>(seq);
}
};
};
}
}}
#endif

View File

@ -0,0 +1,40 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_BEGIN_IMPL_09272006_0719)
#define BOOST_FUSION_BEGIN_IMPL_09272006_0719
#include <boost/fusion/sequence/adapted/boost_tuple/boost_tuple_iterator.hpp>
namespace boost { namespace fusion
{
struct boost_tuple_tag;
namespace extension
{
template<typename T>
struct begin_impl;
template <>
struct begin_impl<boost_tuple_tag>
{
template <typename Sequence>
struct apply
{
typedef boost_tuple_iterator<Sequence> type;
static type
call(Sequence& v)
{
return type(v);
}
};
};
}
}}
#endif

View File

@ -0,0 +1,33 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_CATEGORY_OF_IMPL_09272006_0726)
#define BOOST_FUSION_CATEGORY_OF_IMPL_09272006_0726
namespace boost { namespace fusion
{
struct boost_tuple_tag;
struct forward_traversal_tag;
namespace extension
{
template<typename T>
struct category_of_impl;
template<>
struct category_of_impl<boost_tuple_tag>
{
template<typename T>
struct apply
{
typedef forward_traversal_tag type;
};
};
}
}}
#endif

View File

@ -0,0 +1,55 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_END_IMPL_09272006_0721)
#define BOOST_FUSION_END_IMPL_09272006_0721
#include <boost/fusion/sequence/adapted/boost_tuple/boost_tuple_iterator.hpp>
#include <boost/mpl/if.hpp>
#include <boost/type_traits/is_const.hpp>
namespace boost { namespace tuples
{
struct null_type;
}}
namespace boost { namespace fusion
{
struct boost_tuple_tag;
namespace extension
{
template <typename Tag>
struct end_impl;
template <>
struct end_impl<boost_tuple_tag>
{
template <typename Sequence>
struct apply
{
typedef
boost_tuple_iterator<
typename mpl::if_<
is_const<Sequence>
, tuples::null_type const
, tuples::null_type
>::type
>
type;
static type
call(Sequence& seq)
{
return type(seq);
}
};
};
}
}}
#endif

View File

@ -0,0 +1,31 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_IS_SEQUENCE_IMPL_09272006_0726)
#define BOOST_FUSION_IS_SEQUENCE_IMPL_09272006_0726
#include <boost/mpl/bool.hpp>
namespace boost { namespace fusion
{
struct boost_tuple_tag;
namespace extension
{
template<typename Tag>
struct is_sequence_impl;
template<>
struct is_sequence_impl<boost_tuple_tag>
{
template<typename Sequence>
struct apply : mpl::true_ {};
};
}
}}
#endif

View File

@ -0,0 +1,31 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_IS_VIEW_IMPL_09272006_0725)
#define BOOST_FUSION_IS_VIEW_IMPL_09272006_0725
#include <boost/mpl/bool.hpp>
namespace boost { namespace fusion
{
struct boost_tuple_tag;
namespace extension
{
template<typename Tag>
struct is_view_impl;
template<>
struct is_view_impl<boost_tuple_tag>
{
template<typename T>
struct apply : mpl::false_ {};
};
}
}}
#endif

View File

@ -0,0 +1,32 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_SIZE_IMPL_09272006_0724)
#define BOOST_FUSION_SIZE_IMPL_09272006_0724
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/int.hpp>
namespace boost { namespace fusion
{
struct boost_tuple_tag;
namespace extension
{
template<typename T>
struct size_impl;
template <>
struct size_impl<boost_tuple_tag>
{
template <typename Sequence>
struct apply : mpl::int_<tuples::length<Sequence>::value> {};
};
}
}}
#endif

View File

@ -0,0 +1,31 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_VALUE_AT_IMPL_09262006_1926)
#define BOOST_FUSION_VALUE_AT_IMPL_09262006_1926
#include <boost/tuple/tuple.hpp>
namespace boost { namespace fusion
{
struct boost_tuple_tag;
namespace extension
{
template<typename T>
struct value_at_impl;
template <>
struct value_at_impl<boost_tuple_tag>
{
template <typename Sequence, typename N>
struct apply : tuples::element<N::value, Sequence> {};
};
}
}}
#endif

View File

@ -0,0 +1,56 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#if !defined(BOOST_FUSION_TAG_OF_09262006_1900)
#define BOOST_FUSION_TAG_OF_09262006_1900
#include <boost/fusion/support/tag_of_fwd.hpp>
namespace boost { namespace tuples
{
struct null_type;
template <
class T0, class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8, class T9
>
class tuple;
template <class Head, class Tail>
struct cons;
}}
namespace boost { namespace fusion
{
struct boost_tuple_tag;
namespace traits
{
template <
class T0, class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8, class T9
>
struct tag_of<tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >
{
typedef boost_tuple_tag type;
};
template <class Head, class Tail>
struct tag_of<tuples::cons<Head, Tail> >
{
typedef boost_tuple_tag type;
};
template <>
struct tag_of<tuples::null_type>
{
typedef boost_tuple_tag type;
};
}
}}
#endif

View File

@ -87,16 +87,12 @@ namespace boost { namespace fusion
template <typename Sequence>
explicit cons(
Sequence const& seq
//~ #if defined(BOOST_MSVC)
// VC++ gets confused when RHS is a derived type. It fails to call
// the copy ctor and attempts to call this templated constructor instead.
, typename disable_if<
mpl::or_<
is_convertible<Sequence, cons> // use copy ctor instead
, is_convertible<Sequence, Car> // use copy to car instead
>
>::type* dummy = 0
//~ #endif
)
: car(*fusion::begin(seq))
, cdr(fusion::next(fusion::begin(seq)), mpl::true_()) {}

View File

@ -17,6 +17,7 @@ namespace boost { namespace fusion
{
// Special tags:
struct sequence_facade_tag;
struct boost_tuple_tag; // boost::tuples::tuple tag
struct array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
@ -37,6 +38,9 @@ namespace boost { namespace fusion
struct apply : Sequence::template at<Sequence, N> {};
};
template <>
struct at_impl<boost_tuple_tag>;
template <>
struct at_impl<array_tag>;

View File

@ -14,6 +14,7 @@ namespace boost { namespace fusion
{
// Special tags:
struct sequence_facade_tag; // iterator facade tag
struct boost_tuple_tag; // boost::tuples::tuple tag
struct array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
@ -34,6 +35,9 @@ namespace boost { namespace fusion
struct apply : Sequence::template begin<Sequence> {};
};
template <>
struct begin_impl<boost_tuple_tag>;
template <>
struct begin_impl<array_tag>;

View File

@ -14,6 +14,7 @@ namespace boost { namespace fusion
{
// Special tags:
struct sequence_facade_tag;
struct boost_tuple_tag; // boost::tuples::tuple tag
struct array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
@ -34,6 +35,9 @@ namespace boost { namespace fusion
struct apply : Sequence::template end<Sequence> {};
};
template <>
struct end_impl<boost_tuple_tag>;
template <>
struct end_impl<array_tag>;

View File

@ -15,6 +15,7 @@ namespace boost { namespace fusion
{
// Special tags:
struct sequence_facade_tag;
struct boost_tuple_tag; // boost::tuples::tuple tag
struct array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
@ -35,6 +36,9 @@ namespace boost { namespace fusion
struct apply : Sequence::template size<Sequence> {};
};
template <>
struct size_impl<boost_tuple_tag>;
template <>
struct size_impl<array_tag>;

View File

@ -15,6 +15,7 @@ namespace boost { namespace fusion
{
// Special tags:
struct sequence_facade_tag;
struct boost_tuple_tag; // boost::tuples::tuple tag
struct array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
@ -35,6 +36,9 @@ namespace boost { namespace fusion
struct apply : Sequence::template value_at<Sequence, N> {};
};
template <>
struct value_at_impl<boost_tuple_tag>;
template <>
struct value_at_impl<array_tag>;

View File

@ -15,6 +15,7 @@
namespace boost { namespace fusion
{
// Special tags:
struct boost_tuple_tag; // boost::tuples::tuple tag
struct array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
@ -44,6 +45,9 @@ namespace boost { namespace fusion
struct apply : detail::fusion_category_of<T> {};
};
template <>
struct category_of_impl<boost_tuple_tag>;
template <>
struct category_of_impl<array_tag>;

View File

@ -19,6 +19,7 @@ namespace boost { namespace fusion
{
// Special tags:
struct non_fusion_tag;
struct boost_tuple_tag; // boost::tuples::tuple tag
struct array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
@ -39,6 +40,9 @@ namespace boost { namespace fusion
struct apply : mpl::false_ {};
};
template <>
struct is_sequence_impl<boost_tuple_tag>;
template <>
struct is_sequence_impl<array_tag>;

View File

@ -15,6 +15,7 @@ namespace boost { namespace fusion
{
// Special tags:
struct sequence_facade_tag;
struct boost_tuple_tag; // boost::tuples::tuple tag
struct array_tag; // boost::array tag
struct mpl_sequence_tag; // mpl sequence tag
struct std_pair_tag; // std::pair tag
@ -37,6 +38,9 @@ namespace boost { namespace fusion
struct apply : Sequence::is_view {};
};
template <>
struct is_view_impl<boost_tuple_tag>;
template <>
struct is_view_impl<array_tag>;

View File

@ -20,6 +20,20 @@ namespace boost
{
template <typename T, std::size_t N>
class array; // forward
namespace tuples
{
struct null_type;
template <
class T0, class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8, class T9
>
class tuple;
template <class Head, class Tail>
struct cons;
}
}
namespace boost { namespace fusion
@ -45,6 +59,18 @@ namespace boost { namespace fusion
typedef typename Sequence::fusion_tag type;
};
template <
class T0, class T1, class T2, class T3, class T4,
class T5, class T6, class T7, class T8, class T9
>
struct tag_of<tuples::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> >;
template <class Head, class Tail>
struct tag_of<tuples::cons<Head, Tail> >;
template <>
struct tag_of<tuples::null_type>;
template <typename T, std::size_t N>
struct tag_of<boost::array<T, N> >;

View File

@ -45,6 +45,7 @@ import testing ;
[ run sequence/as_map.cpp : : : : ]
[ run sequence/as_set.cpp : : : : ]
[ run sequence/as_vector.cpp : : : : ]
[ run sequence/boost_tuple.cpp : : : : ]
[ run sequence/cons.cpp : : : : ]
[ run sequence/filter_view.cpp : : : : ]
[ run sequence/io.cpp : : : : ]

View File

@ -0,0 +1,91 @@
/*=============================================================================
Copyright (c) 2001-2006 Joel de Guzman
Use, modification and distribution is subject to the Boost Software
License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
http://www.boost.org/LICENSE_1_0.txt)
==============================================================================*/
#include <boost/detail/lightweight_test.hpp>
#include <boost/fusion/sequence/adapted/boost_tuple.hpp>
#include <boost/fusion/sequence/intrinsic/at.hpp>
#include <boost/fusion/sequence/intrinsic/size.hpp>
#include <boost/fusion/sequence/intrinsic/empty.hpp>
#include <boost/fusion/sequence/intrinsic/front.hpp>
#include <boost/fusion/sequence/intrinsic/back.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/sequence/container/vector/vector.hpp>
#include <boost/fusion/sequence/container/list/list.hpp>
#include <boost/fusion/sequence/generation/make_vector.hpp>
#include <boost/fusion/sequence/conversion/as_vector.hpp>
#include <boost/fusion/sequence/comparison/equal_to.hpp>
#include <boost/fusion/sequence/comparison/not_equal_to.hpp>
#include <boost/fusion/sequence/comparison/less.hpp>
#include <boost/fusion/sequence/comparison/less_equal.hpp>
#include <boost/fusion/sequence/comparison/greater.hpp>
#include <boost/fusion/sequence/comparison/greater_equal.hpp>
#include <boost/fusion/support/is_view.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/mpl/assert.hpp>
#include <iostream>
#include <string>
int
main()
{
using namespace boost::fusion;
using namespace boost;
using namespace std;
std::cout << tuple_open('[');
std::cout << tuple_close(']');
std::cout << tuple_delimiter(", ");
{
typedef boost::tuple<int, std::string> tuple_type;
BOOST_MPL_ASSERT_NOT((traits::is_view<tuple_type>));
tuple_type t(123, "Hola!!!");
std::cout << at_c<0>(t) << std::endl;
std::cout << at_c<1>(t) << std::endl;
std::cout << t << std::endl;
BOOST_TEST(t == make_vector(123, "Hola!!!"));
at_c<0>(t) = 6;
at_c<1>(t) = "mama mia";
BOOST_TEST(t == make_vector(6, "mama mia"));
BOOST_STATIC_ASSERT(result_of::size<tuple_type>::value == 2);
BOOST_STATIC_ASSERT(!result_of::empty<tuple_type>::value);
BOOST_TEST(front(t) == 6);
}
{
fusion::vector<int, float> v1(4, 3.3f);
boost::tuple<short, float> v2(5, 3.3f);
fusion::vector<long, double> v3(5, 4.4);
BOOST_TEST(v1 < v2);
BOOST_TEST(v1 <= v2);
BOOST_TEST(v2 > v1);
BOOST_TEST(v2 >= v1);
BOOST_TEST(v2 < v3);
BOOST_TEST(v2 <= v3);
BOOST_TEST(v3 > v2);
BOOST_TEST(v3 >= v2);
}
{
// conversion from boost tuple to vector
fusion::vector<int, std::string> v(tuples::make_tuple(123, "Hola!!!"));
v = tuples::make_tuple(123, "Hola!!!");
}
{
// conversion from boost tuple to list
fusion::list<int, std::string> l(tuples::make_tuple(123, "Hola!!!"));
l = tuples::make_tuple(123, "Hola!!!");
}
return boost::report_errors();
}