Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/generic/include/boost/multi_index/member.hpp @ 16:2665513ce2d3
Add boost headers
author | Chris Cannam |
---|---|
date | Tue, 05 Aug 2014 11:11:38 +0100 |
parents | |
children | c530137014c0 |
comparison
equal
deleted
inserted
replaced
15:663ca0da4350 | 16:2665513ce2d3 |
---|---|
1 /* Copyright 2003-2008 Joaquin M Lopez Munoz. | |
2 * Distributed under the Boost Software License, Version 1.0. | |
3 * (See accompanying file LICENSE_1_0.txt or copy at | |
4 * http://www.boost.org/LICENSE_1_0.txt) | |
5 * | |
6 * See http://www.boost.org/libs/multi_index for library home page. | |
7 */ | |
8 | |
9 #ifndef BOOST_MULTI_INDEX_MEMBER_HPP | |
10 #define BOOST_MULTI_INDEX_MEMBER_HPP | |
11 | |
12 #if defined(_MSC_VER)&&(_MSC_VER>=1200) | |
13 #pragma once | |
14 #endif | |
15 | |
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ | |
17 #include <boost/mpl/if.hpp> | |
18 #include <boost/type_traits/is_const.hpp> | |
19 #include <boost/utility/enable_if.hpp> | |
20 #include <cstddef> | |
21 | |
22 #if !defined(BOOST_NO_SFINAE) | |
23 #include <boost/type_traits/is_convertible.hpp> | |
24 #endif | |
25 | |
26 namespace boost{ | |
27 | |
28 template<class T> class reference_wrapper; /* fwd decl. */ | |
29 | |
30 namespace multi_index{ | |
31 | |
32 namespace detail{ | |
33 | |
34 /* member is a read/write key extractor for accessing a given | |
35 * member of a class. | |
36 * Additionally, member is overloaded to support referece_wrappers | |
37 * of T and "chained pointers" to T's. By chained pointer to T we mean | |
38 * a type P such that, given a p of Type P | |
39 * *...n...*x is convertible to T&, for some n>=1. | |
40 * Examples of chained pointers are raw and smart pointers, iterators and | |
41 * arbitrary combinations of these (vg. T** or auto_ptr<T*>.) | |
42 */ | |
43 | |
44 /* NB. Some overloads of operator() have an extra dummy parameter int=0. | |
45 * This disambiguator serves several purposes: | |
46 * - Without it, MSVC++ 6.0 incorrectly regards some overloads as | |
47 * specializations of a previous member function template. | |
48 * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns | |
49 * as if they have the same signature. | |
50 * - If remove_const is broken due to lack of PTS, int=0 avoids the | |
51 * declaration of memfuns with identical signature. | |
52 */ | |
53 | |
54 template<class Class,typename Type,Type Class::*PtrToMember> | |
55 struct const_member_base | |
56 { | |
57 typedef Type result_type; | |
58 | |
59 template<typename ChainedPtr> | |
60 | |
61 #if !defined(BOOST_NO_SFINAE) | |
62 typename disable_if< | |
63 is_convertible<const ChainedPtr&,const Class&>,Type&>::type | |
64 #else | |
65 Type& | |
66 #endif | |
67 | |
68 operator()(const ChainedPtr& x)const | |
69 { | |
70 return operator()(*x); | |
71 } | |
72 | |
73 Type& operator()(const Class& x)const | |
74 { | |
75 return x.*PtrToMember; | |
76 } | |
77 | |
78 Type& operator()(const reference_wrapper<const Class>& x)const | |
79 { | |
80 return operator()(x.get()); | |
81 } | |
82 | |
83 Type& operator()(const reference_wrapper<Class>& x,int=0)const | |
84 { | |
85 return operator()(x.get()); | |
86 } | |
87 }; | |
88 | |
89 template<class Class,typename Type,Type Class::*PtrToMember> | |
90 struct non_const_member_base | |
91 { | |
92 typedef Type result_type; | |
93 | |
94 template<typename ChainedPtr> | |
95 | |
96 #if !defined(BOOST_NO_SFINAE) | |
97 typename disable_if< | |
98 is_convertible<const ChainedPtr&,const Class&>,Type&>::type | |
99 #else | |
100 Type& | |
101 #endif | |
102 | |
103 operator()(const ChainedPtr& x)const | |
104 { | |
105 return operator()(*x); | |
106 } | |
107 | |
108 const Type& operator()(const Class& x,int=0)const | |
109 { | |
110 return x.*PtrToMember; | |
111 } | |
112 | |
113 Type& operator()(Class& x)const | |
114 { | |
115 return x.*PtrToMember; | |
116 } | |
117 | |
118 const Type& operator()(const reference_wrapper<const Class>& x,int=0)const | |
119 { | |
120 return operator()(x.get()); | |
121 } | |
122 | |
123 Type& operator()(const reference_wrapper<Class>& x)const | |
124 { | |
125 return operator()(x.get()); | |
126 } | |
127 }; | |
128 | |
129 } /* namespace multi_index::detail */ | |
130 | |
131 template<class Class,typename Type,Type Class::*PtrToMember> | |
132 struct member: | |
133 mpl::if_c< | |
134 is_const<Type>::value, | |
135 detail::const_member_base<Class,Type,PtrToMember>, | |
136 detail::non_const_member_base<Class,Type,PtrToMember> | |
137 >::type | |
138 { | |
139 }; | |
140 | |
141 namespace detail{ | |
142 | |
143 /* MSVC++ 6.0 does not support properly pointers to members as | |
144 * non-type template arguments, as reported in | |
145 * http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045 | |
146 * A similar problem (though not identical) is shown by MSVC++ 7.0. | |
147 * We provide an alternative to member<> accepting offsets instead | |
148 * of pointers to members. This happens to work even for non-POD | |
149 * types (although the standard forbids use of offsetof on these), | |
150 * so it serves as a workaround in this compiler for all practical | |
151 * purposes. | |
152 * Surprisingly enough, other compilers, like Intel C++ 7.0/7.1 and | |
153 * Visual Age 6.0, have similar bugs. This replacement of member<> | |
154 * can be used for them too. | |
155 */ | |
156 | |
157 template<class Class,typename Type,std::size_t OffsetOfMember> | |
158 struct const_member_offset_base | |
159 { | |
160 typedef Type result_type; | |
161 | |
162 template<typename ChainedPtr> | |
163 | |
164 #if !defined(BOOST_NO_SFINAE) | |
165 typename disable_if< | |
166 is_convertible<const ChainedPtr&,const Class&>,Type&>::type | |
167 #else | |
168 Type& | |
169 #endif | |
170 | |
171 operator()(const ChainedPtr& x)const | |
172 { | |
173 return operator()(*x); | |
174 } | |
175 | |
176 Type& operator()(const Class& x)const | |
177 { | |
178 return *static_cast<const Type*>( | |
179 static_cast<const void*>( | |
180 static_cast<const char*>( | |
181 static_cast<const void *>(&x))+OffsetOfMember)); | |
182 } | |
183 | |
184 Type& operator()(const reference_wrapper<const Class>& x)const | |
185 { | |
186 return operator()(x.get()); | |
187 } | |
188 | |
189 Type& operator()(const reference_wrapper<Class>& x,int=0)const | |
190 { | |
191 return operator()(x.get()); | |
192 } | |
193 }; | |
194 | |
195 template<class Class,typename Type,std::size_t OffsetOfMember> | |
196 struct non_const_member_offset_base | |
197 { | |
198 typedef Type result_type; | |
199 | |
200 template<typename ChainedPtr> | |
201 | |
202 #if !defined(BOOST_NO_SFINAE) | |
203 typename disable_if< | |
204 is_convertible<const ChainedPtr&,const Class&>,Type&>::type | |
205 #else | |
206 Type& | |
207 #endif | |
208 | |
209 operator()(const ChainedPtr& x)const | |
210 { | |
211 return operator()(*x); | |
212 } | |
213 | |
214 const Type& operator()(const Class& x,int=0)const | |
215 { | |
216 return *static_cast<const Type*>( | |
217 static_cast<const void*>( | |
218 static_cast<const char*>( | |
219 static_cast<const void *>(&x))+OffsetOfMember)); | |
220 } | |
221 | |
222 Type& operator()(Class& x)const | |
223 { | |
224 return *static_cast<Type*>( | |
225 static_cast<void*>( | |
226 static_cast<char*>(static_cast<void *>(&x))+OffsetOfMember)); | |
227 } | |
228 | |
229 const Type& operator()(const reference_wrapper<const Class>& x,int=0)const | |
230 { | |
231 return operator()(x.get()); | |
232 } | |
233 | |
234 Type& operator()(const reference_wrapper<Class>& x)const | |
235 { | |
236 return operator()(x.get()); | |
237 } | |
238 }; | |
239 | |
240 } /* namespace multi_index::detail */ | |
241 | |
242 template<class Class,typename Type,std::size_t OffsetOfMember> | |
243 struct member_offset: | |
244 mpl::if_c< | |
245 is_const<Type>::value, | |
246 detail::const_member_offset_base<Class,Type,OffsetOfMember>, | |
247 detail::non_const_member_offset_base<Class,Type,OffsetOfMember> | |
248 >::type | |
249 { | |
250 }; | |
251 | |
252 /* BOOST_MULTI_INDEX_MEMBER resolves to member in the normal cases, | |
253 * and to member_offset as a workaround in those defective compilers for | |
254 * which BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is defined. | |
255 */ | |
256 | |
257 #if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) | |
258 #define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ | |
259 ::boost::multi_index::member_offset< Class,Type,offsetof(Class,MemberName) > | |
260 #else | |
261 #define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \ | |
262 ::boost::multi_index::member< Class,Type,&Class::MemberName > | |
263 #endif | |
264 | |
265 } /* namespace multi_index */ | |
266 | |
267 } /* namespace boost */ | |
268 | |
269 #endif |