Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:53:52

0001 ///////////////////////////////////////////////////////////////////////////////
0002 // cons.hpp
0003 //
0004 //  Copyright 2008 Eric Niebler. Distributed under the Boost
0005 //  Software License, Version 1.0. (See accompanying file
0006 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
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 // In Boost 1.33+, we have a cons list in Fusion, so just include it.
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 // For earlier versions of Boost, put the definition of cons here
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     } // namespace cons_detail
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     } // namespace meta
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 }} // namespace boost::fusion
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 }} // namespace boost::mpl
0281 
0282 #endif
0283 
0284 // Before Boost v1.33.1, Fusion cons lists were not valid MPL sequences.
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 }} // namespace boost::mpl
0307 #endif
0308 
0309 #endif