std_tuple.hpp
Go to the documentation of this file.
1 //
2 // Copyright (C) 2014, 2015 Ableton AG, Berlin. All rights reserved.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a
5 // copy of this software and associated documentation files (the "Software"),
6 // to deal in the Software without restriction, including without limitation
7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 // and/or sell copies of the Software, and to permit persons to whom the
9 // Software is furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 // DEALINGS IN THE SOFTWARE.
21 //
22 
27 #pragma once
28 
29 #include <ableton/build_system/Warnings.hpp>
30 ABL_DISABLE_WARNINGS
31 #include <boost/mpl/sequence_tag.hpp>
32 #include <boost/mpl/pop_front_fwd.hpp>
33 #include <boost/mpl/push_front_fwd.hpp>
34 #include <boost/mpl/push_back_fwd.hpp>
35 #include <boost/mpl/front_fwd.hpp>
36 #include <boost/mpl/empty_fwd.hpp>
37 #include <boost/mpl/size_fwd.hpp>
38 #include <boost/mpl/at_fwd.hpp>
39 #include <boost/mpl/back_fwd.hpp>
40 #include <boost/mpl/clear_fwd.hpp>
41 #include <boost/mpl/pop_back_fwd.hpp>
42 #include <boost/mpl/iterator_tags.hpp>
43 #include <boost/mpl/next_prior.hpp>
44 #include <boost/mpl/deref.hpp>
45 #include <boost/mpl/begin_end_fwd.hpp>
46 ABL_RESTORE_WARNINGS
47 #include <tuple>
48 
49 namespace atria {
50 namespace meta {
51 
56 struct std_tuple_tag;
57 
58 template <class ... Args>
60 
61 template <class ... Args>
62 struct std_tuple_iterator<std::tuple<Args...>>
63 {
64  typedef atria::meta::std_tuple_tag tag;
65  typedef boost::mpl::forward_iterator_tag category;
66 };
67 
68 } // namespace meta
69 } // namespace atria
70 
71 namespace boost {
72 namespace mpl {
73 
74 template <class ... Args>
75 struct sequence_tag<std::tuple<Args...>>
76 {
77  typedef atria::meta::std_tuple_tag type;
78 };
79 
80 template <>
81 struct front_impl<atria::meta::std_tuple_tag>
82 {
83  template <typename Tuple>
84  struct apply
85  : std::tuple_element<0, Tuple>
86  {
87  };
88 };
89 
90 template <>
91 struct empty_impl<atria::meta::std_tuple_tag>
92 {
93  template <typename Tuple> struct apply
94  : std::integral_constant<bool, std::tuple_size<Tuple>::value == 0>
95  {
96  };
97 };
98 
99 template <>
100 struct pop_front_impl<atria::meta::std_tuple_tag>
101 {
102  template <typename Tuple> struct apply;
103 
104  template <class First, class ... Types> struct apply<std::tuple<First, Types...>>
105  {
106  typedef std::tuple<Types...> type;
107  };
108 };
109 
110 template <>
111 struct push_front_impl<atria::meta::std_tuple_tag>
112 {
113  template <typename Tuple, typename T> struct apply;
114 
115  template <typename T, typename ... Args>
116  struct apply<std::tuple<Args...>, T>
117  {
118  typedef std::tuple<T, Args...> type;
119  };
120 };
121 
122 template <>
123 struct push_back_impl<atria::meta::std_tuple_tag>
124 {
125  template <typename Tuple, typename T> struct apply;
126 
127  template <typename T, typename ... Args >
128  struct apply<std::tuple<Args...>, T>
129  {
130  typedef std::tuple<Args..., T> type;
131  };
132 };
133 
134 
135 template <>
136 struct size_impl<atria::meta::std_tuple_tag>
137 {
138  template <typename Tuple> struct apply
139  : std::tuple_size<Tuple>
140  {
141  };
142 };
143 
144 template <>
145 struct at_impl<atria::meta::std_tuple_tag>
146 {
147  template <typename Tuple, typename N> struct apply
148  : std::tuple_element<N::value, Tuple>
149  {
150  };
151 };
152 
153 template <>
154 struct back_impl<atria::meta::std_tuple_tag>
155 {
156  template <typename Tuple> struct apply
157  : std::tuple_element<std::tuple_size<Tuple>::value - 1, Tuple>
158  {
159  };
160 };
161 
162 template <>
163 struct clear_impl<atria::meta::std_tuple_tag>
164 {
165  template <typename Tuple> struct apply
166  {
167  typedef std::tuple<> type;
168  };
169 };
170 
171 template <>
172 struct pop_back_impl<atria::meta::std_tuple_tag>
173 {
174  template <int ...> struct tuple_seq {};
175  template <int N, int ...S> struct tuple_gens : tuple_gens<N-1, N-1, S...> {};
176  template <int ...S> struct tuple_gens<0, S...>{ typedef tuple_seq<S...> type; };
177 
178  template <class Tuple, class Index> struct apply_impl;
179  template <class Tuple, int ... S> struct apply_impl<Tuple, tuple_seq<S...>>
180  {
181  typedef std::tuple<typename std::tuple_element<S, Tuple>::type...> type;
182  };
183 
184  template <typename Tuple> struct apply : apply_impl<Tuple, typename tuple_gens<std::tuple_size<Tuple>::value - 1>::type> { };
185 };
186 
187 template <>
188 struct begin_impl<atria::meta::std_tuple_tag>
189 {
190  template <class Tuple> struct apply
191  {
193  };
194 };
195 
196 template <>
197 struct end_impl<atria::meta::std_tuple_tag>
198 {
199  template <typename> struct apply
200  {
202  };
203 };
204 
205 template <typename First, class ... Args>
206 struct deref<atria::meta::std_tuple_iterator<std::tuple<First, Args...>>>
207 {
208  typedef First type;
209 };
210 
211 template <typename First, class ... Args>
212 struct next<atria::meta::std_tuple_iterator<std::tuple<First, Args...>>>
213 {
214  typedef atria::meta::std_tuple_iterator<std::tuple<Args...>> type;
215 };
216 
217 } // namespace mpl
218 } // namespace boost
Definition: pack.hpp:121
STL namespace.
C++ amazing templates and reusable implementations awesomeness.
Definition: _doc.hpp:35
Fork me on GitHub