| 1 | /*============================================================================= |
| 2 | Copyright (c) 2001-2011 Joel de Guzman |
| 3 | Copyright (c) 2005 Eric Niebler |
| 4 | |
| 5 | Distributed under the Boost Software License, Version 1.0. (See accompanying |
| 6 | file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
| 7 | ==============================================================================*/ |
| 8 | #if !defined(FUSION_CONS_07172005_0843) |
| 9 | #define FUSION_CONS_07172005_0843 |
| 10 | |
| 11 | #include <boost/fusion/support/config.hpp> |
| 12 | #include <boost/fusion/support/void.hpp> |
| 13 | #include <boost/fusion/support/detail/enabler.hpp> |
| 14 | #include <boost/fusion/container/list/cons_fwd.hpp> |
| 15 | #include <boost/fusion/support/detail/access.hpp> |
| 16 | #include <boost/fusion/sequence/intrinsic/begin.hpp> |
| 17 | #include <boost/fusion/sequence/intrinsic/end.hpp> |
| 18 | #include <boost/fusion/iterator/next.hpp> |
| 19 | #include <boost/fusion/iterator/deref.hpp> |
| 20 | #include <boost/fusion/container/list/nil.hpp> |
| 21 | #include <boost/fusion/container/list/cons_iterator.hpp> |
| 22 | #include <boost/fusion/container/list/detail/begin_impl.hpp> |
| 23 | #include <boost/fusion/container/list/detail/end_impl.hpp> |
| 24 | #include <boost/fusion/container/list/detail/at_impl.hpp> |
| 25 | #include <boost/fusion/container/list/detail/value_at_impl.hpp> |
| 26 | #include <boost/fusion/container/list/detail/empty_impl.hpp> |
| 27 | #include <boost/type_traits/is_convertible.hpp> |
| 28 | #include <boost/type_traits/is_base_of.hpp> |
| 29 | #include <boost/utility/enable_if.hpp> |
| 30 | #include <boost/fusion/support/sequence_base.hpp> |
| 31 | #include <boost/fusion/support/is_sequence.hpp> |
| 32 | #include <boost/mpl/int.hpp> |
| 33 | #include <boost/mpl/bool.hpp> |
| 34 | #include <boost/mpl/and.hpp> |
| 35 | #include <boost/mpl/not.hpp> |
| 36 | |
| 37 | namespace boost { namespace fusion |
| 38 | { |
| 39 | struct cons_tag; |
| 40 | struct forward_traversal_tag; |
| 41 | struct fusion_sequence_tag; |
| 42 | |
| 43 | template <typename Car, typename Cdr /*= nil_*/> |
| 44 | struct cons : sequence_base<cons<Car, Cdr> > |
| 45 | { |
| 46 | typedef mpl::int_<Cdr::size::value+1> size; |
| 47 | typedef cons_tag fusion_tag; |
| 48 | typedef fusion_sequence_tag tag; // this gets picked up by MPL |
| 49 | typedef mpl::false_ is_view; |
| 50 | typedef forward_traversal_tag category; |
| 51 | typedef Car car_type; |
| 52 | typedef Cdr cdr_type; |
| 53 | |
| 54 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 55 | cons() |
| 56 | : car(), cdr() {} |
| 57 | |
| 58 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 59 | explicit cons(typename detail::call_param<Car>::type in_car) |
| 60 | : car(in_car), cdr() {} |
| 61 | |
| 62 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 63 | cons( |
| 64 | typename detail::call_param<Car>::type in_car |
| 65 | , typename detail::call_param<Cdr>::type in_cdr) |
| 66 | : car(in_car), cdr(in_cdr) {} |
| 67 | |
| 68 | template <typename Car2, typename Cdr2> |
| 69 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 70 | cons(cons<Car2, Cdr2> const& rhs) |
| 71 | : car(rhs.car), cdr(rhs.cdr) {} |
| 72 | |
| 73 | #if BOOST_WORKAROUND(BOOST_GCC, / 100 == 406) && !defined(BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS) |
| 74 | // Workaround for `array used as initializer` compile error on gcc 4.6 w/ c++0x. |
| 75 | template <typename = void> |
| 76 | #endif |
| 77 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 78 | cons(cons const& rhs) |
| 79 | : car(rhs.car), cdr(rhs.cdr) {} |
| 80 | |
| 81 | template <typename Sequence> |
| 82 | BOOST_FUSION_GPU_ENABLED |
| 83 | cons( |
| 84 | Sequence const& seq |
| 85 | , typename boost::enable_if< |
| 86 | mpl::and_< |
| 87 | traits::is_sequence<Sequence> |
| 88 | , mpl::not_<is_base_of<cons, Sequence> > |
| 89 | , mpl::not_<is_convertible<Sequence, Car> > > // use copy to car instead |
| 90 | , detail::enabler_ |
| 91 | >::type = detail::enabler |
| 92 | ) |
| 93 | : car(*fusion::begin(seq)) |
| 94 | , cdr(fusion::next(fusion::begin(seq)), mpl::true_()) {} |
| 95 | |
| 96 | template <typename Iterator> |
| 97 | BOOST_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 98 | cons(Iterator const& iter, mpl::true_ /*this_is_an_iterator*/) |
| 99 | : car(*iter) |
| 100 | , cdr(fusion::next(iter), mpl::true_()) {} |
| 101 | |
| 102 | template <typename Car2, typename Cdr2> |
| 103 | BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 104 | cons& operator=(cons<Car2, Cdr2> const& rhs) |
| 105 | { |
| 106 | car = rhs.car; |
| 107 | cdr = rhs.cdr; |
| 108 | return *this; |
| 109 | } |
| 110 | |
| 111 | BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 112 | cons& operator=(cons const& rhs) |
| 113 | { |
| 114 | car = rhs.car; |
| 115 | cdr = rhs.cdr; |
| 116 | return *this; |
| 117 | } |
| 118 | |
| 119 | template <typename Sequence> |
| 120 | BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 121 | typename boost::enable_if< |
| 122 | mpl::and_< |
| 123 | traits::is_sequence<Sequence> |
| 124 | , mpl::not_<is_convertible<Sequence, Car> > > |
| 125 | , cons&>::type |
| 126 | operator=(Sequence const& seq) |
| 127 | { |
| 128 | typedef typename result_of::begin<Sequence const>::type Iterator; |
| 129 | Iterator iter = fusion::begin(seq); |
| 130 | this->assign_from_iter(iter); |
| 131 | return *this; |
| 132 | } |
| 133 | |
| 134 | template <typename Iterator> |
| 135 | BOOST_CXX14_CONSTEXPR BOOST_FUSION_GPU_ENABLED |
| 136 | void assign_from_iter(Iterator const& iter) |
| 137 | { |
| 138 | car = *iter; |
| 139 | cdr.assign_from_iter(fusion::next(iter)); |
| 140 | } |
| 141 | |
| 142 | car_type car; |
| 143 | cdr_type cdr; |
| 144 | }; |
| 145 | }} |
| 146 | |
| 147 | #endif |
| 148 | |
| 149 | |