source: NonGTP/Boost/boost/multi_index/mem_fun.hpp @ 857

Revision 857, 5.3 KB checked in by igarcia, 18 years ago (diff)
Line 
1/* Copyright 2003-2005 Joaquín M López Muñoz.
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_MEM_FUN_HPP
10#define BOOST_MULTI_INDEX_MEM_FUN_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/remove_reference.hpp>
19
20namespace boost{
21
22template<class T> class reference_wrapper; /* fwd decl. */
23
24namespace multi_index{
25
26/* mem_fun implements a read-only key extractor based on a given non-const
27 * member function of a class.
28 * const_mem_fun does the same for const member functions.
29 * Additionally, mem_fun  and const_mem_fun are overloaded to support
30 * referece_wrappers of T and "chained pointers" to T's. By chained pointer
31 * to T we  mean a type P such that, given a p of Type P
32 *   *...n...*x is convertible to T&, for some n>=1.
33 * Examples of chained pointers are raw and smart pointers, iterators and
34 * arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
35 */
36
37/* NB. Some overloads of operator() have an extra dummy parameter int=0.
38 * This disambiguator serves several purposes:
39 *  - Without it, MSVC++ 6.0 incorrectly regards some overloads as
40 *    specializations of a previous member function template.
41 *  - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
42 *    as if they have the same signature.
43 *  - If remove_const is broken due to lack of PTS, int=0 avoids the
44 *    declaration of memfuns with identical signature.
45 */
46
47template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()const>
48struct const_mem_fun
49{
50  typedef typename remove_reference<Type>::type result_type;
51
52  template<typename ChainedPtr>
53  Type operator()(const ChainedPtr& x)const
54  {
55    return operator()(*x);
56  }
57
58  Type operator()(const Class& x)const
59  {
60    return (x.*PtrToMemberFunction)();
61  }
62
63  Type operator()(const reference_wrapper<const Class>& x)const
64  {
65    return operator()(x.get());
66  }
67
68  Type operator()(const reference_wrapper<Class>& x,int=0)const
69  {
70    return operator()(x.get());
71  }
72};
73
74template<class Class,typename Type,Type (Class::*PtrToMemberFunction)()>
75struct mem_fun
76{
77  typedef typename remove_reference<Type>::type result_type;
78
79  template<typename ChainedPtr>
80  Type operator()(const ChainedPtr& x)const
81  {
82    return operator()(*x);
83  }
84
85  Type operator()(Class& x)const
86  {
87    return (x.*PtrToMemberFunction)();
88  }
89
90  Type operator()(const reference_wrapper<Class>& x)const
91  {
92    return operator()(x.get());
93  }
94};
95
96/* MSVC++ 6.0 has problems with const member functions as non-type template
97 * parameters, somehow it takes them as non-const. mem_fun_explicit workarounds
98 * this defficiency by accepting an extra type parameter that specifies the
99 * signature of he member function. The workaround was found at:
100 *   Daniel, C.:"Re: weird typedef problem in VC",
101 *   news:microsoft.public.vc.language, 21st nov 2002,
102 *   http://groups.google.com/groups?
103 *     hl=en&lr=&ie=UTF-8&selm=ukwvg3O0BHA.1512%40tkmsftngp05
104 */
105
106template<
107  class Class,typename Type,
108  typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction>
109struct const_mem_fun_explicit
110{
111  typedef typename remove_reference<Type>::type result_type;
112
113  template<typename ChainedPtr>
114  Type operator()(const ChainedPtr& x)const
115  {
116    return operator()(*x);
117  }
118
119  Type operator()(const Class& x)const
120  {
121    return (x.*PtrToMemberFunction)();
122  }
123
124  Type operator()(const reference_wrapper<const Class>& x)const
125  {
126    return operator()(x.get());
127  }
128
129  Type operator()(const reference_wrapper<Class>& x,int=0)const
130  {
131    return operator()(x.get());
132  }
133};
134
135template<
136  class Class,typename Type,
137  typename PtrToMemberFunctionType,PtrToMemberFunctionType PtrToMemberFunction>
138struct mem_fun_explicit
139{
140  typedef typename remove_reference<Type>::type result_type;
141
142  template<typename ChainedPtr>
143  Type operator()(const ChainedPtr& x)const
144  {
145    return operator()(*x);
146  }
147
148  Type operator()(Class& x)const
149  {
150    return (x.*PtrToMemberFunction)();
151  }
152
153  Type operator()(const reference_wrapper<Class>& x)const
154  {
155    return operator()(x.get());
156  }
157};
158
159/* BOOST_MULTI_INDEX_CONST_MEM_FUN and BOOST_MULTI_INDEX_MEM_FUN resolve to
160 * mem_fun_explicit for MSVC++ 6.0 and to [const_]mem_fun otherwise.
161 */
162
163#if defined(BOOST_MSVC)&&(BOOST_MSVC<1300)
164
165#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \
166::boost::multi_index::const_mem_fun_explicit<\
167  Class,Type,Type (Class::*)()const,&Class::MemberFunName>
168#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \
169::boost::multi_index::mem_fun_explicit<\
170  Class,Type,Type (Class::*)(),&Class::MemberFunName>
171
172#else
173
174#define BOOST_MULTI_INDEX_CONST_MEM_FUN(Class,Type,MemberFunName) \
175::boost::multi_index::const_mem_fun<Class,Type,&Class::MemberFunName>
176#define BOOST_MULTI_INDEX_MEM_FUN(Class,Type,MemberFunName) \
177::boost::multi_index::mem_fun<Class,Type,&Class::MemberFunName>
178
179#endif
180
181} /* namespace multi_index */
182
183} /* namespace boost */
184
185#endif
Note: See TracBrowser for help on using the repository browser.