/////////////////////////////////////////////////////////////////////////////// // 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 #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 1.35+ has Fusion2 # else # include // Fusion1 # endif #else // For earlier versions of Boost, put the definition of cons here # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include # include namespace boost { namespace fusion { struct nil; struct cons_tag; template struct cons; struct cons_iterator_tag; template struct cons_iterator; namespace cons_detail { template 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 , add_reference::type> , add_reference >::type type; static type call(Iterator const& i) { return detail::ref(i.cons.car); } }; template 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 , add_const , mpl::identity >::type> type; static type call(Iterator const& i) { return type(detail::ref(i.cons.cdr)); } }; template struct value_traits_impl { typedef typename Iterator::cons_type cons_type; typedef typename cons_type::car_type type; }; template struct begin_traits_impl { typedef cons_iterator type; static type call(Cons& t) { return type(t); } }; template struct end_traits_impl { typedef cons_iterator< typename mpl::if_, nil const, nil>::type> type; static type call(Cons& t) { FUSION_RETURN_DEFAULT_CONSTRUCTED; } }; } // namespace cons_detail namespace meta { template struct deref_impl; template <> struct deref_impl { template struct apply : cons_detail::deref_traits_impl {}; }; template struct next_impl; template <> struct next_impl { template struct apply : cons_detail::next_traits_impl {}; }; template struct value_impl; template <> struct value_impl { template struct apply : cons_detail::value_traits_impl {}; }; template struct begin_impl; template <> struct begin_impl { template struct apply : cons_detail::begin_traits_impl {}; }; template struct end_impl; template <> struct end_impl { template struct apply : cons_detail::end_traits_impl {}; }; } // namespace meta template struct cons_iterator : iterator_base > { typedef cons_iterator_tag tag; typedef Cons cons_type; explicit cons_iterator(cons_type& cons_) : cons(cons_) {} cons_type& cons; }; template <> struct cons_iterator : iterator_base > { typedef cons_iterator_tag tag; typedef nil cons_type; cons_iterator() {} explicit cons_iterator(nil const&) {} }; template <> struct cons_iterator : iterator_base > { typedef cons_iterator_tag tag; typedef nil const cons_type; cons_iterator() {} explicit cons_iterator(nil const&) {} }; struct nil : sequence_base { typedef cons_tag tag; typedef void_t car_type; typedef void_t cdr_type; }; template struct cons : sequence_base > { typedef cons_tag tag; typedef typename call_traits::value_type car_type; typedef Cdr cdr_type; cons() : car(), cdr() {} explicit cons( typename call_traits::param_type car_ , typename call_traits::param_type cdr_ = Cdr()) : car(car_), cdr(cdr_) {} car_type car; cdr_type cdr; }; template inline cons make_cons(Car const& car) { return cons(car); } template inline cons make_cons(Car const& car, Cdr const& cdr) { return cons(car, cdr); } }} // namespace boost::fusion namespace boost { namespace mpl { template struct begin_impl; template struct end_impl; template <> struct begin_impl : fusion::meta::begin_impl { }; template <> struct end_impl : fusion::meta::end_impl { }; }} // 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 struct next; template struct next > : fusion::cons_detail::next_traits_impl > { }; template struct deref; template struct deref > : fusion::cons_detail::value_traits_impl > { }; }} // namespace boost::mpl #endif #endif