Chris@16: /////////////////////////////////////////////////////////////////////////////// Chris@16: // cons.hpp Chris@16: // Chris@16: // Copyright 2008 Eric Niebler. Distributed under the Boost Chris@16: // Software License, Version 1.0. (See accompanying file Chris@16: // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #ifndef BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005 Chris@16: #define BOOST_XPRESSIVE_DETAIL_UTILITY_CONS_HPP_EAN_11_19_2005 Chris@16: Chris@16: #include Chris@16: Chris@16: #if BOOST_VERSION >= 103300 Chris@16: Chris@16: // In Boost 1.33+, we have a cons list in Fusion, so just include it. Chris@16: Chris@16: # if BOOST_VERSION >= 103500 Chris@16: # include // Boost 1.35+ has Fusion2 Chris@16: # else Chris@16: # include // Fusion1 Chris@16: # endif Chris@16: Chris@16: #else Chris@16: Chris@16: // For earlier versions of Boost, put the definition of cons here Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: # include Chris@16: Chris@16: namespace boost { namespace fusion Chris@16: { Chris@16: struct nil; Chris@16: Chris@16: struct cons_tag; Chris@16: Chris@16: template Chris@16: struct cons; Chris@16: Chris@16: struct cons_iterator_tag; Chris@16: Chris@16: template Chris@16: struct cons_iterator; Chris@16: Chris@16: namespace cons_detail Chris@16: { Chris@16: template Chris@16: struct deref_traits_impl Chris@16: { Chris@16: typedef typename Iterator::cons_type cons_type; Chris@16: typedef typename cons_type::car_type value_type; Chris@16: Chris@16: typedef typename mpl::eval_if< Chris@16: is_const Chris@16: , add_reference::type> Chris@16: , add_reference >::type Chris@16: type; Chris@16: Chris@16: static type Chris@16: call(Iterator const& i) Chris@16: { Chris@16: return detail::ref(i.cons.car); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct next_traits_impl Chris@16: { Chris@16: typedef typename Iterator::cons_type cons_type; Chris@16: typedef typename cons_type::cdr_type cdr_type; Chris@16: Chris@16: typedef cons_iterator< Chris@16: typename mpl::eval_if< Chris@16: is_const Chris@16: , add_const Chris@16: , mpl::identity Chris@16: >::type> Chris@16: type; Chris@16: Chris@16: static type Chris@16: call(Iterator const& i) Chris@16: { Chris@16: return type(detail::ref(i.cons.cdr)); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct value_traits_impl Chris@16: { Chris@16: typedef typename Iterator::cons_type cons_type; Chris@16: typedef typename cons_type::car_type type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct begin_traits_impl Chris@16: { Chris@16: typedef cons_iterator type; Chris@16: Chris@16: static type Chris@16: call(Cons& t) Chris@16: { Chris@16: return type(t); Chris@16: } Chris@16: }; Chris@16: Chris@16: template Chris@16: struct end_traits_impl Chris@16: { Chris@16: typedef cons_iterator< Chris@16: typename mpl::if_, nil const, nil>::type> Chris@16: type; Chris@16: Chris@16: static type Chris@16: call(Cons& t) Chris@16: { Chris@16: FUSION_RETURN_DEFAULT_CONSTRUCTED; Chris@16: } Chris@16: }; Chris@16: } // namespace cons_detail Chris@16: Chris@16: namespace meta Chris@16: { Chris@16: template Chris@16: struct deref_impl; Chris@16: Chris@16: template <> Chris@16: struct deref_impl Chris@16: { Chris@16: template Chris@16: struct apply : cons_detail::deref_traits_impl {}; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct next_impl; Chris@16: Chris@16: template <> Chris@16: struct next_impl Chris@16: { Chris@16: template Chris@16: struct apply : cons_detail::next_traits_impl {}; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct value_impl; Chris@16: Chris@16: template <> Chris@16: struct value_impl Chris@16: { Chris@16: template Chris@16: struct apply : cons_detail::value_traits_impl {}; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct begin_impl; Chris@16: Chris@16: template <> Chris@16: struct begin_impl Chris@16: { Chris@16: template Chris@16: struct apply : cons_detail::begin_traits_impl Chris@16: {}; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct end_impl; Chris@16: Chris@16: template <> Chris@16: struct end_impl Chris@16: { Chris@16: template Chris@16: struct apply : cons_detail::end_traits_impl Chris@16: {}; Chris@16: }; Chris@16: } // namespace meta Chris@16: Chris@16: template Chris@16: struct cons_iterator : iterator_base > Chris@16: { Chris@16: typedef cons_iterator_tag tag; Chris@16: typedef Cons cons_type; Chris@16: Chris@16: explicit cons_iterator(cons_type& cons_) Chris@16: : cons(cons_) {} Chris@16: Chris@16: cons_type& cons; Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct cons_iterator : iterator_base > Chris@16: { Chris@16: typedef cons_iterator_tag tag; Chris@16: typedef nil cons_type; Chris@16: cons_iterator() {} Chris@16: explicit cons_iterator(nil const&) {} Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct cons_iterator : iterator_base > Chris@16: { Chris@16: typedef cons_iterator_tag tag; Chris@16: typedef nil const cons_type; Chris@16: cons_iterator() {} Chris@16: explicit cons_iterator(nil const&) {} Chris@16: }; Chris@16: Chris@16: struct nil : sequence_base Chris@16: { Chris@16: typedef cons_tag tag; Chris@16: typedef void_t car_type; Chris@16: typedef void_t cdr_type; Chris@16: }; Chris@16: Chris@16: template Chris@16: struct cons : sequence_base > Chris@16: { Chris@16: typedef cons_tag tag; Chris@16: typedef typename call_traits::value_type car_type; Chris@16: typedef Cdr cdr_type; Chris@16: Chris@16: cons() Chris@16: : car(), cdr() {} Chris@16: Chris@16: explicit cons( Chris@16: typename call_traits::param_type car_ Chris@16: , typename call_traits::param_type cdr_ = Cdr()) Chris@16: : car(car_), cdr(cdr_) {} Chris@16: Chris@16: car_type car; Chris@16: cdr_type cdr; Chris@16: }; Chris@16: Chris@16: template Chris@16: inline cons Chris@16: make_cons(Car const& car) Chris@16: { Chris@16: return cons(car); Chris@16: } Chris@16: Chris@16: template Chris@16: inline cons Chris@16: make_cons(Car const& car, Cdr const& cdr) Chris@16: { Chris@16: return cons(car, cdr); Chris@16: } Chris@16: }} // namespace boost::fusion Chris@16: Chris@16: namespace boost { namespace mpl Chris@16: { Chris@16: template Chris@16: struct begin_impl; Chris@16: Chris@16: template Chris@16: struct end_impl; Chris@16: Chris@16: template <> Chris@16: struct begin_impl Chris@16: : fusion::meta::begin_impl Chris@16: { Chris@16: }; Chris@16: Chris@16: template <> Chris@16: struct end_impl Chris@16: : fusion::meta::end_impl Chris@16: { Chris@16: }; Chris@16: Chris@16: }} // namespace boost::mpl Chris@16: Chris@16: #endif Chris@16: Chris@16: // Before Boost v1.33.1, Fusion cons lists were not valid MPL sequences. Chris@16: #if BOOST_VERSION < 103301 Chris@16: namespace boost { namespace mpl Chris@16: { Chris@16: template Chris@16: struct next; Chris@16: Chris@16: template Chris@16: struct next > Chris@16: : fusion::cons_detail::next_traits_impl > Chris@16: { Chris@16: }; Chris@16: Chris@16: template Chris@16: struct deref; Chris@16: Chris@16: template Chris@16: struct deref > Chris@16: : fusion::cons_detail::value_traits_impl > Chris@16: { Chris@16: }; Chris@16: Chris@16: }} // namespace boost::mpl Chris@16: #endif Chris@16: Chris@16: #endif