Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-19 09:47:47

0001 /*=============================================================================
0002     Copyright (c) 2001-2011 Hartmut Kaiser
0003     Copyright (c) 2001-2011 Joel de Guzman
0004 
0005     Distributed under the Boost Software License, Version 1.0. (See accompanying
0006     file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0007 ==============================================================================*/
0008 #if !defined(BOOST_SPIRIT_ANY_IF_MARCH_30_2007_1220PM)
0009 #define BOOST_SPIRIT_ANY_IF_MARCH_30_2007_1220PM
0010 
0011 #if defined(_MSC_VER)
0012 #pragma once
0013 #endif
0014 
0015 #include <boost/fusion/include/equal_to.hpp>
0016 #include <boost/fusion/include/next.hpp>
0017 #include <boost/fusion/include/deref.hpp>
0018 #include <boost/fusion/include/value_of.hpp>
0019 #include <boost/fusion/include/begin.hpp>
0020 #include <boost/fusion/include/end.hpp>
0021 #include <boost/fusion/include/is_sequence.hpp>
0022 #include <boost/fusion/include/any.hpp>
0023 #include <boost/spirit/home/support/unused.hpp>
0024 
0025 #include <boost/mpl/bool.hpp>
0026 #include <boost/mpl/apply.hpp>
0027 #include <boost/mpl/if.hpp>
0028 #include <boost/mpl/identity.hpp>
0029 #include <boost/mpl/and.hpp>
0030 #include <boost/mpl/not.hpp>
0031 
0032 namespace boost { namespace spirit
0033 {
0034     ///////////////////////////////////////////////////////////////////////////
0035     //  This is a special version for a binary fusion::any. The predicate
0036     //  is used to decide whether to advance the second iterator or not.
0037     //  This is needed for sequences containing components with unused
0038     //  attributes. The second iterator is advanced only if the attribute
0039     //  of the corresponding component iterator is not unused.
0040     ///////////////////////////////////////////////////////////////////////////
0041     namespace detail
0042     {
0043         ///////////////////////////////////////////////////////////////////////
0044         template <typename Iterator, typename Pred>
0045         struct apply_predicate
0046           : mpl::apply1<Pred, typename fusion::result_of::value_of<Iterator>::type>
0047         {};
0048 
0049         ///////////////////////////////////////////////////////////////////////
0050         //  if the predicate is true, attribute_next returns next(Iterator2),
0051         //  otherwise Iterator2
0052         namespace result_of
0053         {
0054             template <
0055                 typename Iterator1, typename Iterator2, typename Last2
0056               , typename Pred>
0057             struct attribute_next
0058             {
0059                 typedef mpl::and_<
0060                     apply_predicate<Iterator1, Pred>
0061                   , mpl::not_<fusion::result_of::equal_to<Iterator2, Last2> >
0062                 > pred;
0063 
0064                 typedef typename
0065                     mpl::eval_if<
0066                         pred
0067                       , fusion::result_of::next<Iterator2>
0068                       , mpl::identity<Iterator2>
0069                     >::type
0070                 type;
0071 
0072                 template <typename Iterator>
0073                 static type
0074                 call(Iterator const& i, mpl::true_)
0075                 {
0076                     return fusion::next(i);
0077                 }
0078 
0079                 template <typename Iterator>
0080                 static type
0081                 call(Iterator const& i, mpl::false_)
0082                 {
0083                     return i;
0084                 }
0085 
0086                 template <typename Iterator>
0087                 static type
0088                 call(Iterator const& i)
0089                 {
0090                     return call(i, pred());
0091                 }
0092             };
0093         }
0094 
0095         template <
0096             typename Pred, typename Iterator1, typename Last2
0097           , typename Iterator2>
0098         inline typename
0099             result_of::attribute_next<Iterator1, Iterator2, Last2, Pred
0100         >::type const
0101         attribute_next(Iterator2 const& i)
0102         {
0103             return result_of::attribute_next<
0104                 Iterator1, Iterator2, Last2, Pred>::call(i);
0105         }
0106 
0107         ///////////////////////////////////////////////////////////////////////
0108         //  if the predicate is true, attribute_value returns deref(Iterator2),
0109         //  otherwise unused
0110         namespace result_of
0111         {
0112             template <
0113                 typename Iterator1, typename Iterator2, typename Last2
0114               , typename Pred>
0115             struct attribute_value
0116             {
0117                 typedef mpl::and_<
0118                     apply_predicate<Iterator1, Pred>
0119                   , mpl::not_<fusion::result_of::equal_to<Iterator2, Last2> >
0120                 > pred;
0121 
0122                 typedef typename
0123                     mpl::eval_if<
0124                         pred
0125                       , fusion::result_of::deref<Iterator2>
0126                       , mpl::identity<unused_type const>
0127                     >::type
0128                 type;
0129 
0130                 template <typename Iterator>
0131                 static type
0132                 call(Iterator const& i, mpl::true_)
0133                 {
0134                     return fusion::deref(i);
0135                 }
0136 
0137                 template <typename Iterator>
0138                 static type
0139                 call(Iterator const&, mpl::false_)
0140                 {
0141                     return unused;
0142                 }
0143 
0144                 template <typename Iterator>
0145                 static type
0146                 call(Iterator const& i)
0147                 {
0148                     return call(i, pred());
0149                 }
0150             };
0151         }
0152 
0153         template <
0154             typename Pred, typename Iterator1, typename Last2
0155           , typename Iterator2>
0156         inline typename
0157             result_of::attribute_value<Iterator1, Iterator2, Last2, Pred
0158         >::type
0159         attribute_value(Iterator2 const& i)
0160         {
0161             return result_of::attribute_value<
0162                 Iterator1, Iterator2, Last2, Pred>::call(i);
0163         }
0164 
0165         ///////////////////////////////////////////////////////////////////////
0166         template <
0167             typename Pred, typename First1, typename Last1, typename First2
0168           , typename Last2, typename F>
0169         inline bool
0170         any_if (First1 const&, First2 const&, Last1 const&, Last2 const&
0171           , F const&, mpl::true_)
0172         {
0173             return false;
0174         }
0175 
0176         template <
0177             typename Pred, typename First1, typename Last1, typename First2
0178           , typename Last2, typename F>
0179         inline bool
0180         any_if (First1 const& first1, First2 const& first2, Last1 const& last1
0181           , Last2 const& last2, F& f, mpl::false_)
0182         {
0183             typename result_of::attribute_value<First1, First2, Last2, Pred>::type
0184                 attribute = spirit::detail::attribute_value<Pred, First1, Last2>(first2);
0185 
0186             return f(*first1, attribute) ||
0187                 detail::any_if<Pred>(
0188                     fusion::next(first1)
0189                   , attribute_next<Pred, First1, Last2>(first2)
0190                   , last1, last2
0191                   , f
0192                   , fusion::result_of::equal_to<
0193                         typename fusion::result_of::next<First1>::type, Last1>());
0194         }
0195     }
0196 
0197     template <typename Pred, typename Sequence1, typename Sequence2, typename F>
0198     inline bool
0199     any_if(Sequence1 const& seq1, Sequence2& seq2, F f, Pred)
0200     {
0201         return detail::any_if<Pred>(
0202                 fusion::begin(seq1), fusion::begin(seq2)
0203               , fusion::end(seq1), fusion::end(seq2)
0204               , f
0205               , fusion::result_of::equal_to<
0206                     typename fusion::result_of::begin<Sequence1>::type
0207                   , typename fusion::result_of::end<Sequence1>::type>());
0208     }
0209 
0210     template <typename Pred, typename Sequence, typename F>
0211     inline bool
0212     any_if(Sequence const& seq, unused_type const, F f, Pred)
0213     {
0214         return fusion::any(seq, f);
0215     }
0216 
0217 }}
0218 
0219 #endif
0220