1 /*=============================================================================
2 Copyright (c) 2001-2011 Joel de Guzman
4 Distributed under the Boost Software License, Version 1.0. (See accompanying
5 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 ==============================================================================*/
7 // No include guard. This file is meant to be included many times
9 #if !defined(FUSION_MACRO_05042005)
10 #define FUSION_MACRO_05042005
12 #define FUSION_VECTOR_CTOR_DEFAULT_INIT(z, n, _) \
15 #define FUSION_VECTOR_CTOR_INIT(z, n, _) \
18 #define FUSION_VECTOR_MEMBER_CTOR_INIT(z, n, _) \
21 #define FUSION_VECTOR_CTOR_FORWARD(z, n, _) \
22 m##n(std::forward<T##n>(other.m##n))
24 #define FUSION_VECTOR_CTOR_ARG_FWD(z, n, _) \
25 m##n(std::forward<U##n>(_##n))
27 #define FUSION_VECTOR_MEMBER_DECL(z, n, _) \
30 #define FUSION_VECTOR_MEMBER_FORWARD(z, n, _) \
31 std::forward<U##n>(_##n)
33 #define FUSION_VECTOR_MEMBER_ASSIGN(z, n, _) \
34 this->BOOST_PP_CAT(m, n) = vec.BOOST_PP_CAT(m, n);
36 #define FUSION_VECTOR_MEMBER_DEREF_ASSIGN(z, n, _) \
37 this->BOOST_PP_CAT(m, n) = *BOOST_PP_CAT(i, n);
39 #define FUSION_VECTOR_MEMBER_MOVE(z, n, _) \
40 this->BOOST_PP_CAT(m, n) = std::forward< \
41 BOOST_PP_CAT(T, n)>(vec.BOOST_PP_CAT(m, n));
43 #define FUSION_VECTOR_MEMBER_AT_IMPL(z, n, _) \
44 typename add_reference<T##n>::type \
45 at_impl(mpl::int_<n>) { return this->m##n; } \
46 typename add_reference<typename add_const<T##n>::type>::type \
47 at_impl(mpl::int_<n>) const { return this->m##n; }
49 #define FUSION_VECTOR_MEMBER_ITER_DECL_VAR(z, n, _) \
50 typedef typename result_of::next< \
51 BOOST_PP_CAT(I, BOOST_PP_DEC(n))>::type BOOST_PP_CAT(I, n); \
52 BOOST_PP_CAT(I, n) BOOST_PP_CAT(i, n) \
53 = fusion::next(BOOST_PP_CAT(i, BOOST_PP_DEC(n)));
57 #define N BOOST_PP_ITERATION()
59 template <BOOST_PP_ENUM_PARAMS(N, typename T)>
60 struct BOOST_PP_CAT(vector_data, N)
62 BOOST_PP_CAT(vector_data, N)()
63 : BOOST_PP_ENUM(N, FUSION_VECTOR_CTOR_DEFAULT_INIT, _) {}
65 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
66 template <BOOST_PP_ENUM_PARAMS(N, typename U)>
67 BOOST_PP_CAT(vector_data, N)(BOOST_PP_ENUM_BINARY_PARAMS(N, U, && _)
68 , typename boost::enable_if<is_convertible<U0, T0> >::type* /*dummy*/ = 0
70 : BOOST_PP_ENUM(N, FUSION_VECTOR_CTOR_ARG_FWD, _) {}
73 BOOST_PP_CAT(vector_data, N)(
74 BOOST_PP_ENUM_BINARY_PARAMS(
75 N, typename detail::call_param<T, >::type _))
76 : BOOST_PP_ENUM(N, FUSION_VECTOR_CTOR_INIT, _) {}
78 BOOST_PP_CAT(vector_data, N)(
79 BOOST_PP_CAT(vector_data, N) const& other)
80 : BOOST_PP_ENUM(N, FUSION_VECTOR_MEMBER_CTOR_INIT, _) {}
82 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
83 BOOST_PP_CAT(vector_data, N)(
84 BOOST_PP_CAT(vector_data, N)&& other)
85 : BOOST_PP_ENUM(N, FUSION_VECTOR_CTOR_FORWARD, _) {}
88 BOOST_PP_CAT(vector_data, N)&
89 operator=(BOOST_PP_CAT(vector_data, N) const& vec)
91 BOOST_PP_REPEAT(N, FUSION_VECTOR_MEMBER_ASSIGN, _)
95 template <typename Sequence>
96 static BOOST_PP_CAT(vector_data, N)
97 init_from_sequence(Sequence const& seq)
99 typedef typename result_of::begin<Sequence const>::type I0;
100 I0 i0 = fusion::begin(seq);
101 BOOST_PP_REPEAT_FROM_TO(1, N, FUSION_VECTOR_MEMBER_ITER_DECL_VAR, _)
102 return BOOST_PP_CAT(vector_data, N)(BOOST_PP_ENUM_PARAMS(N, *i));
105 template <typename Sequence>
106 static BOOST_PP_CAT(vector_data, N)
107 init_from_sequence(Sequence& seq)
109 typedef typename result_of::begin<Sequence>::type I0;
110 I0 i0 = fusion::begin(seq);
111 BOOST_PP_REPEAT_FROM_TO(1, N, FUSION_VECTOR_MEMBER_ITER_DECL_VAR, _)
112 return BOOST_PP_CAT(vector_data, N)(BOOST_PP_ENUM_PARAMS(N, *i));
115 BOOST_PP_REPEAT(N, FUSION_VECTOR_MEMBER_DECL, _)
118 template <BOOST_PP_ENUM_PARAMS(N, typename T)>
119 struct BOOST_PP_CAT(vector, N)
120 : BOOST_PP_CAT(vector_data, N)<BOOST_PP_ENUM_PARAMS(N, T)>
121 , sequence_base<BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, T)> >
123 typedef BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, T)> this_type;
124 typedef BOOST_PP_CAT(vector_data, N)<BOOST_PP_ENUM_PARAMS(N, T)> base_type;
125 typedef mpl::BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, T)> types;
126 typedef vector_tag fusion_tag;
127 typedef fusion_sequence_tag tag; // this gets picked up by MPL
128 typedef mpl::false_ is_view;
129 typedef random_access_traversal_tag category;
130 typedef mpl::int_<N> size;
132 BOOST_PP_CAT(vector, N)() {}
137 BOOST_PP_CAT(vector, N)(
138 BOOST_PP_ENUM_BINARY_PARAMS(
139 N, typename detail::call_param<T, >::type _))
140 : base_type(BOOST_PP_ENUM_PARAMS(N, _)) {}
142 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
143 template <BOOST_PP_ENUM_PARAMS(N, typename U)>
146 BOOST_PP_CAT(vector, N)(U0&& _0
147 , typename boost::enable_if<is_convertible<U0, T0> >::type* /*dummy*/ = 0
149 : base_type(std::forward<U0>(_0)) {}
151 BOOST_PP_CAT(vector, N)(BOOST_PP_ENUM_BINARY_PARAMS(N, U, && _))
152 : base_type(BOOST_PP_ENUM(N, FUSION_VECTOR_MEMBER_FORWARD, _)) {}
155 BOOST_PP_CAT(vector, N)(BOOST_PP_CAT(vector, N)&& rhs)
156 : base_type(std::forward<base_type>(rhs)) {}
158 BOOST_PP_CAT(vector, N)(BOOST_PP_CAT(vector, N) const& rhs)
163 template <BOOST_PP_ENUM_PARAMS(N, typename U)>
164 BOOST_PP_CAT(vector, N)(
165 BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, U)> const& vec)
166 : base_type(BOOST_PP_ENUM_PARAMS(N, vec.m)) {}
168 template <typename Sequence>
169 BOOST_PP_CAT(vector, N)(
172 , typename boost::disable_if<is_convertible<Sequence, T0> >::type* /*dummy*/ = 0
175 : base_type(base_type::init_from_sequence(seq)) {}
177 template <typename Sequence>
178 BOOST_PP_CAT(vector, N)(
181 , typename boost::disable_if<is_convertible<Sequence, T0> >::type* /*dummy*/ = 0
184 : base_type(base_type::init_from_sequence(seq)) {}
186 template <BOOST_PP_ENUM_PARAMS(N, typename U)>
187 BOOST_PP_CAT(vector, N)&
188 operator=(BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, U)> const& vec)
190 BOOST_PP_REPEAT(N, FUSION_VECTOR_MEMBER_ASSIGN, _)
194 template <typename Sequence>
195 typename boost::disable_if<is_convertible<Sequence, T0>, this_type&>::type
196 operator=(Sequence const& seq)
198 typedef typename result_of::begin<Sequence const>::type I0;
199 I0 i0 = fusion::begin(seq);
200 BOOST_PP_REPEAT_FROM_TO(1, N, FUSION_VECTOR_MEMBER_ITER_DECL_VAR, _)
201 BOOST_PP_REPEAT(N, FUSION_VECTOR_MEMBER_DEREF_ASSIGN, _)
205 #if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES)
206 BOOST_PP_CAT(vector, N)&
207 operator=(BOOST_PP_CAT(vector, N) const& vec)
209 base_type::operator=(vec);
213 BOOST_PP_CAT(vector, N)&
214 operator=(BOOST_PP_CAT(vector, N)&& vec)
216 BOOST_PP_REPEAT(N, FUSION_VECTOR_MEMBER_MOVE, _)
221 BOOST_PP_REPEAT(N, FUSION_VECTOR_MEMBER_AT_IMPL, _)
224 typename add_reference<typename mpl::at<types, I>::type>::type
227 return this->at_impl(mpl::int_<I::value>());
231 typename add_reference<typename add_const<typename mpl::at<types, I>::type>::type>::type
234 return this->at_impl(mpl::int_<I::value>());