From 483eb2f56657e8e7f419ab1a4fab8dce9ade8609 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sat, 27 Apr 2024 20:24:20 +0200 Subject: Adding upstream version 14.2.21. Signed-off-by: Daniel Baumann --- src/boost/libs/fusion/example/extension/triple.cpp | 377 +++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 src/boost/libs/fusion/example/extension/triple.cpp (limited to 'src/boost/libs/fusion/example/extension/triple.cpp') diff --git a/src/boost/libs/fusion/example/extension/triple.cpp b/src/boost/libs/fusion/example/extension/triple.cpp new file mode 100644 index 00000000..ac8f18e0 --- /dev/null +++ b/src/boost/libs/fusion/example/extension/triple.cpp @@ -0,0 +1,377 @@ +/*============================================================================= + Copyright (c) 2001-2011 Joel de Guzman + Copyright (c) 2011 Nathan Ridge + 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 + +#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 Sq::t0_type& type; + + static type + call(triple_iterator const& iter) + { + return iter.seq_.t0; + } + }; + + template + struct deref const> + { + typedef typename Sq::t0_type const& type; + + static type + call(triple_iterator const& iter) + { + return iter.seq_.t0; + } + }; + + template + struct deref > + { + typedef typename Sq::t1_type& type; + + static type + call(triple_iterator const& iter) + { + return iter.seq_.t1; + } + }; + + template + struct deref const> + { + typedef typename Sq::t1_type const& type; + + static type + call(triple_iterator const& iter) + { + return iter.seq_.t1; + } + }; + + template + struct deref > + { + typedef typename Sq::t2_type& type; + + static type + call(triple_iterator const& iter) + { + return iter.seq_.t2; + } + }; + + template + struct deref const> + { + typedef typename Sq::t2_type const& 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< + typename It2::index, typename It1::index>::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 type; + + static type call(Sq& sq) + { + return type(sq); + } + }; + + template + struct end + { + typedef demo::triple_iterator 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; + }; +} + +struct modifying_fold_functor +{ + template + struct result + { + typedef bool type; + }; + + template + bool operator()(bool b, T&) + { + return b; + } +}; + +struct nonmodifying_fold_functor +{ + template + struct result + { + typedef bool type; + }; + + template + bool operator()(bool b, const T&) + { + return b; + } +}; + +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< + int, fusion::result_of::value_at_c::type>)); + BOOST_MPL_ASSERT((boost::is_same< + char, fusion::result_of::value_at_c::type>)); + BOOST_MPL_ASSERT((boost::is_same< + std::string, fusion::result_of::value_at_c::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"); + BOOST_TEST(fusion::fold(t, true, modifying_fold_functor()) == true); + BOOST_TEST(fusion::fold(t, true, nonmodifying_fold_functor()) == true); + return boost::report_errors(); +} -- cgit v1.2.3