File indexing completed on 2025-01-18 09:53:52
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005
0009 #define BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005
0010
0011 #include <boost/version.hpp>
0012
0013 #if BOOST_VERSION >= 103300
0014
0015
0016
0017 # if BOOST_VERSION >= 103500
0018 # include <boost/fusion/include/cons.hpp> // Boost 1.35+ has Fusion2
0019 # else
0020 # include <boost/spirit/fusion/sequence/cons.hpp> // Fusion1
0021 # endif
0022
0023 #else
0024
0025
0026 # include <boost/call_traits.hpp>
0027 # include <boost/mpl/if.hpp>
0028 # include <boost/mpl/eval_if.hpp>
0029 # include <boost/mpl/identity.hpp>
0030 # include <boost/type_traits/is_const.hpp>
0031 # include <boost/type_traits/add_const.hpp>
0032 # include <boost/type_traits/add_reference.hpp>
0033 # include <boost/spirit/fusion/detail/config.hpp>
0034 # include <boost/spirit/fusion/detail/access.hpp>
0035 # include <boost/spirit/fusion/iterator/next.hpp>
0036 # include <boost/spirit/fusion/iterator/equal_to.hpp>
0037 # include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp>
0038 # include <boost/spirit/fusion/iterator/detail/iterator_base.hpp>
0039 # include <boost/spirit/fusion/sequence/begin.hpp>
0040 # include <boost/spirit/fusion/sequence/end.hpp>
0041 # include <boost/spirit/fusion/sequence/as_fusion_sequence.hpp>
0042 # include <boost/spirit/fusion/sequence/detail/sequence_base.hpp>
0043
0044 namespace boost { namespace fusion
0045 {
0046 struct nil;
0047
0048 struct cons_tag;
0049
0050 template <typename Car, typename Cdr>
0051 struct cons;
0052
0053 struct cons_iterator_tag;
0054
0055 template <typename Cons>
0056 struct cons_iterator;
0057
0058 namespace cons_detail
0059 {
0060 template <typename Iterator>
0061 struct deref_traits_impl
0062 {
0063 typedef typename Iterator::cons_type cons_type;
0064 typedef typename cons_type::car_type value_type;
0065
0066 typedef typename mpl::eval_if<
0067 is_const<cons_type>
0068 , add_reference<typename add_const<value_type>::type>
0069 , add_reference<value_type> >::type
0070 type;
0071
0072 static type
0073 call(Iterator const& i)
0074 {
0075 return detail::ref(i.cons.car);
0076 }
0077 };
0078
0079 template <typename Iterator>
0080 struct next_traits_impl
0081 {
0082 typedef typename Iterator::cons_type cons_type;
0083 typedef typename cons_type::cdr_type cdr_type;
0084
0085 typedef cons_iterator<
0086 typename mpl::eval_if<
0087 is_const<cons_type>
0088 , add_const<cdr_type>
0089 , mpl::identity<cdr_type>
0090 >::type>
0091 type;
0092
0093 static type
0094 call(Iterator const& i)
0095 {
0096 return type(detail::ref(i.cons.cdr));
0097 }
0098 };
0099
0100 template <typename Iterator>
0101 struct value_traits_impl
0102 {
0103 typedef typename Iterator::cons_type cons_type;
0104 typedef typename cons_type::car_type type;
0105 };
0106
0107 template <typename Cons>
0108 struct begin_traits_impl
0109 {
0110 typedef cons_iterator<Cons> type;
0111
0112 static type
0113 call(Cons& t)
0114 {
0115 return type(t);
0116 }
0117 };
0118
0119 template <typename Cons>
0120 struct end_traits_impl
0121 {
0122 typedef cons_iterator<
0123 typename mpl::if_<is_const<Cons>, nil const, nil>::type>
0124 type;
0125
0126 static type
0127 call(Cons& t)
0128 {
0129 FUSION_RETURN_DEFAULT_CONSTRUCTED;
0130 }
0131 };
0132 }
0133
0134 namespace meta
0135 {
0136 template <typename Tag>
0137 struct deref_impl;
0138
0139 template <>
0140 struct deref_impl<cons_iterator_tag>
0141 {
0142 template <typename Iterator>
0143 struct apply : cons_detail::deref_traits_impl<Iterator> {};
0144 };
0145
0146 template <typename Tag>
0147 struct next_impl;
0148
0149 template <>
0150 struct next_impl<cons_iterator_tag>
0151 {
0152 template <typename Iterator>
0153 struct apply : cons_detail::next_traits_impl<Iterator> {};
0154 };
0155
0156 template <typename Tag>
0157 struct value_impl;
0158
0159 template <>
0160 struct value_impl<cons_iterator_tag>
0161 {
0162 template <typename Iterator>
0163 struct apply : cons_detail::value_traits_impl<Iterator> {};
0164 };
0165
0166 template <typename Tag>
0167 struct begin_impl;
0168
0169 template <>
0170 struct begin_impl<cons_tag>
0171 {
0172 template <typename Sequence>
0173 struct apply : cons_detail::begin_traits_impl<Sequence>
0174 {};
0175 };
0176
0177 template <typename Tag>
0178 struct end_impl;
0179
0180 template <>
0181 struct end_impl<cons_tag>
0182 {
0183 template <typename Sequence>
0184 struct apply : cons_detail::end_traits_impl<Sequence>
0185 {};
0186 };
0187 }
0188
0189 template <typename Cons = nil>
0190 struct cons_iterator : iterator_base<cons_iterator<Cons> >
0191 {
0192 typedef cons_iterator_tag tag;
0193 typedef Cons cons_type;
0194
0195 explicit cons_iterator(cons_type& cons_)
0196 : cons(cons_) {}
0197
0198 cons_type& cons;
0199 };
0200
0201 template <>
0202 struct cons_iterator<nil> : iterator_base<cons_iterator<nil> >
0203 {
0204 typedef cons_iterator_tag tag;
0205 typedef nil cons_type;
0206 cons_iterator() {}
0207 explicit cons_iterator(nil const&) {}
0208 };
0209
0210 template <>
0211 struct cons_iterator<nil const> : iterator_base<cons_iterator<nil const> >
0212 {
0213 typedef cons_iterator_tag tag;
0214 typedef nil const cons_type;
0215 cons_iterator() {}
0216 explicit cons_iterator(nil const&) {}
0217 };
0218
0219 struct nil : sequence_base<nil>
0220 {
0221 typedef cons_tag tag;
0222 typedef void_t car_type;
0223 typedef void_t cdr_type;
0224 };
0225
0226 template <typename Car, typename Cdr = nil>
0227 struct cons : sequence_base<cons<Car,Cdr> >
0228 {
0229 typedef cons_tag tag;
0230 typedef typename call_traits<Car>::value_type car_type;
0231 typedef Cdr cdr_type;
0232
0233 cons()
0234 : car(), cdr() {}
0235
0236 explicit cons(
0237 typename call_traits<Car>::param_type car_
0238 , typename call_traits<Cdr>::param_type cdr_ = Cdr())
0239 : car(car_), cdr(cdr_) {}
0240
0241 car_type car;
0242 cdr_type cdr;
0243 };
0244
0245 template <typename Car>
0246 inline cons<Car>
0247 make_cons(Car const& car)
0248 {
0249 return cons<Car>(car);
0250 }
0251
0252 template <typename Car, typename Cdr>
0253 inline cons<Car, Cdr>
0254 make_cons(Car const& car, Cdr const& cdr)
0255 {
0256 return cons<Car, Cdr>(car, cdr);
0257 }
0258 }}
0259
0260 namespace boost { namespace mpl
0261 {
0262 template <typename Tag>
0263 struct begin_impl;
0264
0265 template <typename Tag>
0266 struct end_impl;
0267
0268 template <>
0269 struct begin_impl<fusion::cons_tag>
0270 : fusion::meta::begin_impl<fusion::cons_tag>
0271 {
0272 };
0273
0274 template <>
0275 struct end_impl<fusion::cons_tag>
0276 : fusion::meta::end_impl<fusion::cons_tag>
0277 {
0278 };
0279
0280 }}
0281
0282 #endif
0283
0284
0285 #if BOOST_VERSION < 103301
0286 namespace boost { namespace mpl
0287 {
0288 template<typename Iterator>
0289 struct next;
0290
0291 template<typename Cons>
0292 struct next<fusion::cons_iterator<Cons> >
0293 : fusion::cons_detail::next_traits_impl<fusion::cons_iterator<Cons> >
0294 {
0295 };
0296
0297 template<typename Iterator>
0298 struct deref;
0299
0300 template<typename Cons>
0301 struct deref<fusion::cons_iterator<Cons> >
0302 : fusion::cons_detail::value_traits_impl<fusion::cons_iterator<Cons> >
0303 {
0304 };
0305
0306 }}
0307 #endif
0308
0309 #endif