| /////////////////////////////////////////////////////////////////////////////// |
| // cons.hpp |
| // |
| // Copyright 2008 Eric Niebler. 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) |
| |
| #ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005 |
| #define BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005 |
| |
| #include <boost/version.hpp> |
| |
| #if BOOST_VERSION >= 103300 |
| |
| // In Boost 1.33+, we have a cons list in Fusion, so just include it. |
| |
| # if BOOST_VERSION >= 103500 |
| # include <boost/fusion/include/cons.hpp> // Boost 1.35+ has Fusion2 |
| # else |
| # include <boost/spirit/fusion/sequence/cons.hpp> // Fusion1 |
| # endif |
| |
| #else |
| |
| // For earlier versions of Boost, put the definition of cons here |
| # include <boost/call_traits.hpp> |
| # include <boost/mpl/if.hpp> |
| # include <boost/mpl/eval_if.hpp> |
| # include <boost/mpl/identity.hpp> |
| # include <boost/type_traits/is_const.hpp> |
| # include <boost/type_traits/add_const.hpp> |
| # include <boost/type_traits/add_reference.hpp> |
| # include <boost/spirit/fusion/detail/config.hpp> |
| # include <boost/spirit/fusion/detail/access.hpp> |
| # include <boost/spirit/fusion/iterator/next.hpp> |
| # include <boost/spirit/fusion/iterator/equal_to.hpp> |
| # include <boost/spirit/fusion/iterator/as_fusion_iterator.hpp> |
| # include <boost/spirit/fusion/iterator/detail/iterator_base.hpp> |
| # include <boost/spirit/fusion/sequence/begin.hpp> |
| # include <boost/spirit/fusion/sequence/end.hpp> |
| # include <boost/spirit/fusion/sequence/as_fusion_sequence.hpp> |
| # include <boost/spirit/fusion/sequence/detail/sequence_base.hpp> |
| |
| namespace boost { namespace fusion |
| { |
| struct nil; |
| |
| struct cons_tag; |
| |
| template <typename Car, typename Cdr> |
| struct cons; |
| |
| struct cons_iterator_tag; |
| |
| template <typename Cons> |
| struct cons_iterator; |
| |
| namespace cons_detail |
| { |
| template <typename Iterator> |
| struct deref_traits_impl |
| { |
| typedef typename Iterator::cons_type cons_type; |
| typedef typename cons_type::car_type value_type; |
| |
| typedef typename mpl::eval_if< |
| is_const<cons_type> |
| , add_reference<typename add_const<value_type>::type> |
| , add_reference<value_type> >::type |
| type; |
| |
| static type |
| call(Iterator const& i) |
| { |
| return detail::ref(i.cons.car); |
| } |
| }; |
| |
| template <typename Iterator> |
| struct next_traits_impl |
| { |
| typedef typename Iterator::cons_type cons_type; |
| typedef typename cons_type::cdr_type cdr_type; |
| |
| typedef cons_iterator< |
| typename mpl::eval_if< |
| is_const<cons_type> |
| , add_const<cdr_type> |
| , mpl::identity<cdr_type> |
| >::type> |
| type; |
| |
| static type |
| call(Iterator const& i) |
| { |
| return type(detail::ref(i.cons.cdr)); |
| } |
| }; |
| |
| template <typename Iterator> |
| struct value_traits_impl |
| { |
| typedef typename Iterator::cons_type cons_type; |
| typedef typename cons_type::car_type type; |
| }; |
| |
| template <typename Cons> |
| struct begin_traits_impl |
| { |
| typedef cons_iterator<Cons> type; |
| |
| static type |
| call(Cons& t) |
| { |
| return type(t); |
| } |
| }; |
| |
| template <typename Cons> |
| struct end_traits_impl |
| { |
| typedef cons_iterator< |
| typename mpl::if_<is_const<Cons>, nil const, nil>::type> |
| type; |
| |
| static type |
| call(Cons& t) |
| { |
| FUSION_RETURN_DEFAULT_CONSTRUCTED; |
| } |
| }; |
| } // namespace cons_detail |
| |
| namespace meta |
| { |
| template <typename Tag> |
| struct deref_impl; |
| |
| template <> |
| struct deref_impl<cons_iterator_tag> |
| { |
| template <typename Iterator> |
| struct apply : cons_detail::deref_traits_impl<Iterator> {}; |
| }; |
| |
| template <typename Tag> |
| struct next_impl; |
| |
| template <> |
| struct next_impl<cons_iterator_tag> |
| { |
| template <typename Iterator> |
| struct apply : cons_detail::next_traits_impl<Iterator> {}; |
| }; |
| |
| template <typename Tag> |
| struct value_impl; |
| |
| template <> |
| struct value_impl<cons_iterator_tag> |
| { |
| template <typename Iterator> |
| struct apply : cons_detail::value_traits_impl<Iterator> {}; |
| }; |
| |
| template <typename Tag> |
| struct begin_impl; |
| |
| template <> |
| struct begin_impl<cons_tag> |
| { |
| template <typename Sequence> |
| struct apply : cons_detail::begin_traits_impl<Sequence> |
| {}; |
| }; |
| |
| template <typename Tag> |
| struct end_impl; |
| |
| template <> |
| struct end_impl<cons_tag> |
| { |
| template <typename Sequence> |
| struct apply : cons_detail::end_traits_impl<Sequence> |
| {}; |
| }; |
| } // namespace meta |
| |
| template <typename Cons = nil> |
| struct cons_iterator : iterator_base<cons_iterator<Cons> > |
| { |
| typedef cons_iterator_tag tag; |
| typedef Cons cons_type; |
| |
| explicit cons_iterator(cons_type& cons_) |
| : cons(cons_) {} |
| |
| cons_type& cons; |
| }; |
| |
| template <> |
| struct cons_iterator<nil> : iterator_base<cons_iterator<nil> > |
| { |
| typedef cons_iterator_tag tag; |
| typedef nil cons_type; |
| cons_iterator() {} |
| explicit cons_iterator(nil const&) {} |
| }; |
| |
| template <> |
| struct cons_iterator<nil const> : iterator_base<cons_iterator<nil const> > |
| { |
| typedef cons_iterator_tag tag; |
| typedef nil const cons_type; |
| cons_iterator() {} |
| explicit cons_iterator(nil const&) {} |
| }; |
| |
| struct nil : sequence_base<nil> |
| { |
| typedef cons_tag tag; |
| typedef void_t car_type; |
| typedef void_t cdr_type; |
| }; |
| |
| template <typename Car, typename Cdr = nil> |
| struct cons : sequence_base<cons<Car,Cdr> > |
| { |
| typedef cons_tag tag; |
| typedef typename call_traits<Car>::value_type car_type; |
| typedef Cdr cdr_type; |
| |
| cons() |
| : car(), cdr() {} |
| |
| explicit cons( |
| typename call_traits<Car>::param_type car_ |
| , typename call_traits<Cdr>::param_type cdr_ = Cdr()) |
| : car(car_), cdr(cdr_) {} |
| |
| car_type car; |
| cdr_type cdr; |
| }; |
| |
| template <typename Car> |
| inline cons<Car> |
| make_cons(Car const& car) |
| { |
| return cons<Car>(car); |
| } |
| |
| template <typename Car, typename Cdr> |
| inline cons<Car, Cdr> |
| make_cons(Car const& car, Cdr const& cdr) |
| { |
| return cons<Car, Cdr>(car, cdr); |
| } |
| }} // namespace boost::fusion |
| |
| namespace boost { namespace mpl |
| { |
| template <typename Tag> |
| struct begin_impl; |
| |
| template <typename Tag> |
| struct end_impl; |
| |
| template <> |
| struct begin_impl<fusion::cons_tag> |
| : fusion::meta::begin_impl<fusion::cons_tag> |
| { |
| }; |
| |
| template <> |
| struct end_impl<fusion::cons_tag> |
| : fusion::meta::end_impl<fusion::cons_tag> |
| { |
| }; |
| |
| }} // namespace boost::mpl |
| |
| #endif |
| |
| // Before Boost v1.33.1, Fusion cons lists were not valid MPL sequences. |
| #if BOOST_VERSION < 103301 |
| namespace boost { namespace mpl |
| { |
| template<typename Iterator> |
| struct next; |
| |
| template<typename Cons> |
| struct next<fusion::cons_iterator<Cons> > |
| : fusion::cons_detail::next_traits_impl<fusion::cons_iterator<Cons> > |
| { |
| }; |
| |
| template<typename Iterator> |
| struct deref; |
| |
| template<typename Cons> |
| struct deref<fusion::cons_iterator<Cons> > |
| : fusion::cons_detail::value_traits_impl<fusion::cons_iterator<Cons> > |
| { |
| }; |
| |
| }} // namespace boost::mpl |
| #endif |
| |
| #endif |