File indexing completed on 2025-01-19 09:47:47
0001
0002
0003
0004
0005
0006
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
0036
0037
0038
0039
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
0051
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
0109
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