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