Boost logo

Boost-Commit :

From: danmarsden_at_[hidden]
Date: 2007-11-06 15:55:59


Author: danmarsden
Date: 2007-11-06 15:55:58 EST (Tue, 06 Nov 2007)
New Revision: 40853
URL: http://svn.boost.org/trac/boost/changeset/40853

Log:
Adding an example of using sequence facade and iterator facade.
Added:
   trunk/libs/fusion/example/extension/triple.cpp (contents, props changed)
Text files modified:
   trunk/libs/fusion/example/extension/Jamfile | 4 +++-
   1 files changed, 3 insertions(+), 1 deletions(-)

Modified: trunk/libs/fusion/example/extension/Jamfile
==============================================================================
--- trunk/libs/fusion/example/extension/Jamfile (original)
+++ trunk/libs/fusion/example/extension/Jamfile 2007-11-06 15:55:58 EST (Tue, 06 Nov 2007)
@@ -13,6 +13,8 @@
 {
     test-suite example :
 
- [ run test_example.cpp : : : : ] ;
+ [ run test_example.cpp : : : : ]
+ [ run triple.cpp : : : : ]
+ ;
 }
 

Added: trunk/libs/fusion/example/extension/triple.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/fusion/example/extension/triple.cpp 2007-11-06 15:55:58 EST (Tue, 06 Nov 2007)
@@ -0,0 +1,319 @@
+/*=============================================================================
+ Copyright (c) 2001-2006 Joel de Guzman
+ Copyright (c) 2006 Dan Marsden
+
+ Distributed under 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)
+==============================================================================*/
+
+/*=============================================================================
+ An implementation of a std::pair like triple<T0, T1, T2>
+ We use fusion::sequence_facade and fusion::iterator_facade
+ to make our triple a fully conforming Boost.Fusion random
+ traversal sequence.
+==============================================================================*/
+
+#include <boost/detail/lightweight_test.hpp>
+
+#include <boost/fusion/sequence/sequence_facade.hpp>
+#include <boost/fusion/iterator/iterator_facade.hpp>
+
+#include <boost/fusion/sequence/intrinsic.hpp>
+#include <boost/fusion/iterator.hpp>
+
+#include <boost/fusion/support/category_of.hpp>
+
+#include <boost/mpl/int.hpp>
+#include <boost/mpl/identity.hpp>
+#include <boost/mpl/minus.hpp>
+#include <boost/mpl/assert.hpp>
+
+#include <boost/type_traits/is_const.hpp>
+#include <boost/type_traits/is_same.hpp>
+
+#include <string>
+
+namespace mpl = boost::mpl;
+namespace fusion = boost::fusion;
+
+namespace demo
+{
+ template<typename Seq, int N>
+ struct triple_iterator
+ : fusion::iterator_facade<triple_iterator<Seq, N>, fusion::random_access_traversal_tag>
+ {
+ typedef mpl::int_<N> index;
+ typedef Seq sequence_type;
+
+ triple_iterator(Seq& seq)
+ : seq_(seq) {}
+
+ Seq& seq_;
+
+ template<typename T>
+ struct value_of;
+
+ template<typename Sq>
+ struct value_of<triple_iterator<Sq, 0> >
+ : mpl::identity<typename Sq::t0_type>
+ {};
+
+ template<typename Sq>
+ struct value_of<triple_iterator<Sq, 1> >
+ : mpl::identity<typename Sq::t1_type>
+ {};
+
+ template<typename Sq>
+ struct value_of<triple_iterator<Sq, 2> >
+ : mpl::identity<typename Sq::t2_type>
+ {};
+
+ template<typename T>
+ struct deref;
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 0> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t0_type const&
+ , typename Sq::t0_type&
+ >::type
+ type;
+
+ static type
+ call(triple_iterator<Sq, 0> const& iter)
+ {
+ return iter.seq_.t0;
+ }
+ };
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 1> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t1_type const&
+ , typename Sq::t1_type&
+ >::type
+ type;
+
+ static type
+ call(triple_iterator<Sq, 1> const& iter)
+ {
+ return iter.seq_.t1;
+ }
+ };
+
+ template <typename Sq>
+ struct deref<triple_iterator<Sq, 2> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t2_type const&
+ , typename Sq::t2_type&
+ >::type
+ type;
+
+ static type
+ call(triple_iterator<Sq, 2> const& iter)
+ {
+ return iter.seq_.t2;
+ }
+ };
+
+ template<typename It>
+ struct next
+ {
+ typedef triple_iterator<
+ typename It::sequence_type, It::index::value + 1> type;
+
+ static type call(It const& it)
+ {
+ return type(it.seq_);
+ }
+ };
+
+ template<typename It>
+ struct prior
+ {
+ typedef triple_iterator<
+ typename It::sequence_type, It::index::value - 1> type;
+
+ static type call(It const& it)
+ {
+ return type(it.seq_);
+ }
+ };
+
+ template<typename It1, typename It2>
+ struct distance
+ {
+ typedef typename mpl::minus<typename It2::index, typename It1::index>::type type;
+
+ static type call(It1 const& it1, It2 const& it2)
+ {
+ return type();
+ }
+ };
+
+ template<typename It, typename M>
+ struct advance
+ {
+ typedef triple_iterator<
+ typename It::sequence_type,
+ It::index::value + M::value> type;
+
+ static type call(It const& it)
+ {
+ return type(it.seq_);
+ }
+ };
+ };
+
+ template<typename T0, typename T1, typename T2>
+ struct triple
+ : fusion::sequence_facade<triple<T0, T1, T2>, fusion::random_access_traversal_tag>
+ {
+ triple(T0 const& t0, T1 const& t1, T2 const& t2)
+ : t0(t0), t1(t1), t2(t2)
+ {}
+
+ template<typename Sq>
+ struct begin
+ {
+ typedef demo::triple_iterator<
+ Sq, 0> type;
+
+ static type call(Sq& sq)
+ {
+ return type(sq);
+ }
+ };
+
+ template<typename Sq>
+ struct end
+ {
+ typedef demo::triple_iterator<
+ Sq, 3> type;
+
+ static type call(Sq& sq)
+ {
+ return type(sq);
+ }
+ };
+
+ template<typename Sq>
+ struct size
+ : mpl::int_<3>
+ {};
+
+ template<typename Sq, typename N>
+ struct value_at
+ : value_at<Sq, mpl::int_<N::value> >
+ {};
+
+ template<typename Sq>
+ struct value_at<Sq, mpl::int_<0> >
+ {
+ typedef typename Sq::t0_type type;
+ };
+
+ template<typename Sq>
+ struct value_at<Sq, mpl::int_<1> >
+ {
+ typedef typename Sq::t1_type type;
+ };
+
+ template<typename Sq>
+ struct value_at<Sq, mpl::int_<2> >
+ {
+ typedef typename Sq::t2_type type;
+ };
+
+ template<typename Sq, typename N>
+ struct at
+ : at<Sq, mpl::int_<N::value> >
+ {};
+
+ template<typename Sq>
+ struct at<Sq, mpl::int_<0> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t0_type const&
+ , typename Sq::t0_type&
+ >::type
+ type;
+
+ static type call(Sq& sq)
+ {
+ return sq.t0;
+ }
+ };
+
+ template<typename Sq>
+ struct at<Sq, mpl::int_<1> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t1_type const&
+ , typename Sq::t1_type&
+ >::type
+ type;
+
+ static type call(Sq& sq)
+ {
+ return sq.t1;
+ }
+ };
+
+ template<typename Sq>
+ struct at<Sq, mpl::int_<2> >
+ {
+ typedef typename
+ mpl::if_<
+ boost::is_const<Sq>
+ , typename Sq::t2_type const&
+ , typename Sq::t2_type&
+ >::type
+ type;
+
+ static type call(Sq& sq)
+ {
+ return sq.t2;
+ }
+ };
+
+ typedef T0 t0_type;
+ typedef T1 t1_type;
+ typedef T2 t2_type;
+
+ T0 t0;
+ T1 t1;
+ T2 t2;
+ };
+}
+
+int main()
+{
+ typedef demo::triple<int, char, std::string> my_triple;
+ my_triple t(101, 'a', "hello");
+ BOOST_TEST(*fusion::begin(t) == 101);
+ BOOST_TEST(*fusion::next(fusion::begin(t)) == 'a');
+ BOOST_TEST(*fusion::prior(fusion::end(t)) == "hello");
+ BOOST_TEST(fusion::distance(fusion::begin(t), fusion::end(t)) == 3);
+ BOOST_TEST(fusion::size(t) == 3);
+ BOOST_MPL_ASSERT((boost::is_same<int, fusion::result_of::value_at_c<my_triple, 0>::type>));
+ BOOST_MPL_ASSERT((boost::is_same<char, fusion::result_of::value_at_c<my_triple, 1>::type>));
+ BOOST_MPL_ASSERT((boost::is_same<std::string, fusion::result_of::value_at_c<my_triple, 2>::type>));
+ BOOST_TEST(fusion::at_c<0>(t) == 101);
+ BOOST_TEST(fusion::at_c<1>(t) == 'a');
+ BOOST_TEST(fusion::at_c<2>(t) == "hello");
+ return boost::report_errors();
+}


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk