123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- ///////////////////////////////////////////////////////////////////////////////
- // 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
|