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