]> git.donarmstrong.com Git - rsem.git/blob - boost/fusion/container/vector/detail/vector_n.hpp
ea314ac28e16a0d6a0c4f883325347c90ec57ea6
[rsem.git] / boost / fusion / container / vector / detail / vector_n.hpp
1 /*=============================================================================
2     Copyright (c) 2001-2006 Joel de Guzman
3
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
8
9 #if !defined(FUSION_MACRO_05042005)
10 #define FUSION_MACRO_05042005
11
12 #define FUSION_MEMBER_DEFAULT_INIT(z, n, _)     m##n()
13 #define FUSION_MEMBER_INIT(z, n, _)             m##n(_##n)
14 #define FUSION_COPY_INIT(z, n, _)               m##n(other.m##n)
15 #define FUSION_MEMBER_DECL(z, n, _)             T##n m##n;
16
17 #define FUSION_MEMBER_ASSIGN(z, n, _)                                           \
18     this->BOOST_PP_CAT(m, n) = vec.BOOST_PP_CAT(m, n);
19
20 #define FUSION_DEREF_MEMBER_ASSIGN(z, n, _)                                     \
21     this->BOOST_PP_CAT(m, n) = *BOOST_PP_CAT(i, n);
22
23 #define FUSION_AT_IMPL(z, n, _)                                                 \
24     typename add_reference<T##n>::type                                          \
25         at_impl(mpl::int_<n>) { return this->m##n; }                            \
26     typename add_reference<typename add_const<T##n>::type>::type                \
27         at_impl(mpl::int_<n>) const { return this->m##n; }
28
29 #define FUSION_ITER_DECL_VAR(z, n, _)                                           \
30     typedef typename result_of::next<                                           \
31         BOOST_PP_CAT(I, BOOST_PP_DEC(n))>::type BOOST_PP_CAT(I, n);             \
32     BOOST_PP_CAT(I, n) BOOST_PP_CAT(i, n)                                       \
33         = fusion::next(BOOST_PP_CAT(i, BOOST_PP_DEC(n)));
34
35 #endif
36
37 #define N BOOST_PP_ITERATION()
38
39     template <typename Derived, BOOST_PP_ENUM_PARAMS(N, typename T)>
40     struct BOOST_PP_CAT(vector_data, N) : sequence_base<Derived>
41     {
42         BOOST_PP_CAT(vector_data, N)()
43             : BOOST_PP_ENUM(N, FUSION_MEMBER_DEFAULT_INIT, _) {}
44
45         BOOST_PP_CAT(vector_data, N)(
46             BOOST_PP_ENUM_BINARY_PARAMS(
47                 N, typename detail::call_param<T, >::type _))
48             : BOOST_PP_ENUM(N, FUSION_MEMBER_INIT, _) {}
49
50         BOOST_PP_CAT(vector_data, N)(
51             BOOST_PP_CAT(vector_data, N) const& other)
52             : BOOST_PP_ENUM(N, FUSION_COPY_INIT, _) {}
53
54         BOOST_PP_CAT(vector_data, N)&
55         operator=(BOOST_PP_CAT(vector_data, N) const& vec)
56         {
57             BOOST_PP_REPEAT(N, FUSION_MEMBER_ASSIGN, _)
58             return *this;
59         }
60
61         template <typename Sequence>
62         static BOOST_PP_CAT(vector_data, N)
63         init_from_sequence(Sequence const& seq)
64         {
65             typedef typename result_of::begin<Sequence const>::type I0;
66             I0 i0 = fusion::begin(seq);
67             BOOST_PP_REPEAT_FROM_TO(1, N, FUSION_ITER_DECL_VAR, _)
68             return BOOST_PP_CAT(vector_data, N)(BOOST_PP_ENUM_PARAMS(N, *i));
69         }
70
71         BOOST_PP_REPEAT(N, FUSION_MEMBER_DECL, _)
72     };
73
74     template <BOOST_PP_ENUM_PARAMS(N, typename T)>
75     struct BOOST_PP_CAT(vector, N)
76         : BOOST_PP_CAT(vector_data, N)<
77             BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, T)>
78           , BOOST_PP_ENUM_PARAMS(N, T)>
79     {
80         typedef BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, T)> this_type;
81         typedef BOOST_PP_CAT(vector_data, N)<this_type, BOOST_PP_ENUM_PARAMS(N, T)> base_type;
82         typedef mpl::BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, T)> types;
83         typedef vector_tag fusion_tag;
84         typedef fusion_sequence_tag tag; // this gets picked up by MPL
85         typedef mpl::false_ is_view;
86         typedef random_access_traversal_tag category;
87         typedef mpl::int_<N> size;
88
89         BOOST_PP_CAT(vector, N)() {}
90
91 #if (N == 1)
92         explicit
93 #endif
94         BOOST_PP_CAT(vector, N)(
95             BOOST_PP_ENUM_BINARY_PARAMS(
96                 N, typename detail::call_param<T, >::type _))
97             : base_type(BOOST_PP_ENUM_PARAMS(N, _)) {}
98
99         template <BOOST_PP_ENUM_PARAMS(N, typename U)>
100         BOOST_PP_CAT(vector, N)(
101             BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, U)> const& vec)
102             : base_type(BOOST_PP_ENUM_PARAMS(N, vec.m)) {}
103
104         template <typename Sequence>
105         BOOST_PP_CAT(vector, N)(
106             Sequence const& seq
107 #if (N == 1)
108           , typename disable_if<is_convertible<Sequence, T0> >::type* /*dummy*/ = 0
109 #endif
110             )
111             : base_type(base_type::init_from_sequence(seq)) {}
112
113         template <BOOST_PP_ENUM_PARAMS(N, typename U)>
114         BOOST_PP_CAT(vector, N)&
115         operator=(BOOST_PP_CAT(vector, N)<BOOST_PP_ENUM_PARAMS(N, U)> const& vec)
116         {
117             BOOST_PP_REPEAT(N, FUSION_MEMBER_ASSIGN, _)
118             return *this;
119         }
120
121         template <typename Sequence>
122         typename disable_if<is_convertible<Sequence, T0>, this_type&>::type
123         operator=(Sequence const& seq)
124         {
125             typedef typename result_of::begin<Sequence const>::type I0;
126             I0 i0 = fusion::begin(seq);
127             BOOST_PP_REPEAT_FROM_TO(1, N, FUSION_ITER_DECL_VAR, _)
128             BOOST_PP_REPEAT(N, FUSION_DEREF_MEMBER_ASSIGN, _)
129             return *this;
130         }
131
132         BOOST_PP_REPEAT(N, FUSION_AT_IMPL, _)
133
134         template<typename I>
135         typename add_reference<typename mpl::at<types, I>::type>::type
136         at_impl(I)
137         {
138             return this->at_impl(mpl::int_<I::value>());
139         }
140
141         template<typename I>
142         typename add_reference<typename add_const<typename mpl::at<types, I>::type>::type>::type
143         at_impl(I) const
144         {
145             return this->at_impl(mpl::int_<I::value>());
146         }
147     };
148
149 #undef N
150