From 353bf4bc09839de7106326d00ed20fda0d48272e Mon Sep 17 00:00:00 2001 From: Dan Marsden Date: Tue, 6 Nov 2007 20:55:58 +0000 Subject: [PATCH] Adding an example of using sequence facade and iterator facade. [SVN r40853] --- example/extension/Jamfile | 4 +- example/extension/triple.cpp | 319 +++++++++++++++++++++++++++++++++++ 2 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 example/extension/triple.cpp diff --git a/example/extension/Jamfile b/example/extension/Jamfile index cf062603..aabe8302 100644 --- a/example/extension/Jamfile +++ b/example/extension/Jamfile @@ -13,6 +13,8 @@ import testing ; { test-suite example : - [ run test_example.cpp : : : : ] ; + [ run test_example.cpp : : : : ] + [ run triple.cpp : : : : ] + ; } diff --git a/example/extension/triple.cpp b/example/extension/triple.cpp new file mode 100644 index 00000000..ee247439 --- /dev/null +++ b/example/extension/triple.cpp @@ -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 + We use fusion::sequence_facade and fusion::iterator_facade + to make our triple a fully conforming Boost.Fusion random + traversal sequence. +==============================================================================*/ + +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +#include +#include + +#include + +namespace mpl = boost::mpl; +namespace fusion = boost::fusion; + +namespace demo +{ + template + struct triple_iterator + : fusion::iterator_facade, fusion::random_access_traversal_tag> + { + typedef mpl::int_ index; + typedef Seq sequence_type; + + triple_iterator(Seq& seq) + : seq_(seq) {} + + Seq& seq_; + + template + struct value_of; + + template + struct value_of > + : mpl::identity + {}; + + template + struct value_of > + : mpl::identity + {}; + + template + struct value_of > + : mpl::identity + {}; + + template + struct deref; + + template + struct deref > + { + typedef typename + mpl::if_< + boost::is_const + , typename Sq::t0_type const& + , typename Sq::t0_type& + >::type + type; + + static type + call(triple_iterator const& iter) + { + return iter.seq_.t0; + } + }; + + template + struct deref > + { + typedef typename + mpl::if_< + boost::is_const + , typename Sq::t1_type const& + , typename Sq::t1_type& + >::type + type; + + static type + call(triple_iterator const& iter) + { + return iter.seq_.t1; + } + }; + + template + struct deref > + { + typedef typename + mpl::if_< + boost::is_const + , typename Sq::t2_type const& + , typename Sq::t2_type& + >::type + type; + + static type + call(triple_iterator const& iter) + { + return iter.seq_.t2; + } + }; + + template + 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 + 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 + struct distance + { + typedef typename mpl::minus::type type; + + static type call(It1 const& it1, It2 const& it2) + { + return type(); + } + }; + + template + 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 + struct triple + : fusion::sequence_facade, fusion::random_access_traversal_tag> + { + triple(T0 const& t0, T1 const& t1, T2 const& t2) + : t0(t0), t1(t1), t2(t2) + {} + + template + struct begin + { + typedef demo::triple_iterator< + Sq, 0> type; + + static type call(Sq& sq) + { + return type(sq); + } + }; + + template + struct end + { + typedef demo::triple_iterator< + Sq, 3> type; + + static type call(Sq& sq) + { + return type(sq); + } + }; + + template + struct size + : mpl::int_<3> + {}; + + template + struct value_at + : value_at > + {}; + + template + struct value_at > + { + typedef typename Sq::t0_type type; + }; + + template + struct value_at > + { + typedef typename Sq::t1_type type; + }; + + template + struct value_at > + { + typedef typename Sq::t2_type type; + }; + + template + struct at + : at > + {}; + + template + struct at > + { + typedef typename + mpl::if_< + boost::is_const + , typename Sq::t0_type const& + , typename Sq::t0_type& + >::type + type; + + static type call(Sq& sq) + { + return sq.t0; + } + }; + + template + struct at > + { + typedef typename + mpl::if_< + boost::is_const + , typename Sq::t1_type const& + , typename Sq::t1_type& + >::type + type; + + static type call(Sq& sq) + { + return sq.t1; + } + }; + + template + struct at > + { + typedef typename + mpl::if_< + boost::is_const + , 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 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::type>)); + BOOST_MPL_ASSERT((boost::is_same::type>)); + BOOST_MPL_ASSERT((boost::is_same::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(); +}