File indexing completed on 2025-01-30 09:48:21
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_MULTI_INDEX_MEMBER_HPP
0010 #define BOOST_MULTI_INDEX_MEMBER_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0017 #include <boost/core/enable_if.hpp>
0018 #include <boost/mpl/if.hpp>
0019 #include <boost/type_traits/is_const.hpp>
0020 #include <cstddef>
0021
0022 #if !defined(BOOST_NO_SFINAE)
0023 #include <boost/type_traits/is_convertible.hpp>
0024 #endif
0025
0026 namespace boost{
0027
0028 template<class T> class reference_wrapper;
0029
0030 namespace multi_index{
0031
0032 namespace detail{
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 template<class Class,typename Type,Type Class::*PtrToMember>
0045 struct const_member_base
0046 {
0047 typedef Type result_type;
0048
0049 template<typename ChainedPtr>
0050
0051 #if !defined(BOOST_NO_SFINAE)
0052 typename disable_if<
0053 is_convertible<const ChainedPtr&,const Class&>,Type&>::type
0054 #else
0055 Type&
0056 #endif
0057
0058 operator()(const ChainedPtr& x)const
0059 {
0060 return operator()(*x);
0061 }
0062
0063 Type& operator()(const Class& x)const
0064 {
0065 return x.*PtrToMember;
0066 }
0067
0068 Type& operator()(const reference_wrapper<const Class>& x)const
0069 {
0070 return operator()(x.get());
0071 }
0072
0073 Type& operator()(const reference_wrapper<Class>& x)const
0074 {
0075 return operator()(x.get());
0076 }
0077 };
0078
0079 template<class Class,typename Type,Type Class::*PtrToMember>
0080 struct non_const_member_base
0081 {
0082 typedef Type result_type;
0083
0084 template<typename ChainedPtr>
0085
0086 #if !defined(BOOST_NO_SFINAE)
0087 typename disable_if<
0088 is_convertible<const ChainedPtr&,const Class&>,Type&>::type
0089 #else
0090 Type&
0091 #endif
0092
0093 operator()(const ChainedPtr& x)const
0094 {
0095 return operator()(*x);
0096 }
0097
0098 const Type& operator()(const Class& x)const
0099 {
0100 return x.*PtrToMember;
0101 }
0102
0103 Type& operator()(Class& x)const
0104 {
0105 return x.*PtrToMember;
0106 }
0107
0108 const Type& operator()(const reference_wrapper<const Class>& x)const
0109 {
0110 return operator()(x.get());
0111 }
0112
0113 Type& operator()(const reference_wrapper<Class>& x)const
0114 {
0115 return operator()(x.get());
0116 }
0117 };
0118
0119 }
0120
0121 template<class Class,typename Type,Type Class::*PtrToMember>
0122 struct member:
0123 mpl::if_c<
0124 is_const<Type>::value,
0125 detail::const_member_base<Class,Type,PtrToMember>,
0126 detail::non_const_member_base<Class,Type,PtrToMember>
0127 >::type
0128 {
0129 };
0130
0131 namespace detail{
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 template<class Class,typename Type,std::size_t OffsetOfMember>
0151 struct const_member_offset_base
0152 {
0153 typedef Type result_type;
0154
0155 template<typename ChainedPtr>
0156
0157 #if !defined(BOOST_NO_SFINAE)
0158 typename disable_if<
0159 is_convertible<const ChainedPtr&,const Class&>,Type&>::type
0160 #else
0161 Type&
0162 #endif
0163
0164 operator()(const ChainedPtr& x)const
0165 {
0166 return operator()(*x);
0167 }
0168
0169 Type& operator()(const Class& x)const
0170 {
0171 return *static_cast<const Type*>(
0172 static_cast<const void*>(
0173 static_cast<const char*>(
0174 static_cast<const void *>(&x))+OffsetOfMember));
0175 }
0176
0177 Type& operator()(const reference_wrapper<const Class>& x)const
0178 {
0179 return operator()(x.get());
0180 }
0181
0182 Type& operator()(const reference_wrapper<Class>& x)const
0183 {
0184 return operator()(x.get());
0185 }
0186 };
0187
0188 template<class Class,typename Type,std::size_t OffsetOfMember>
0189 struct non_const_member_offset_base
0190 {
0191 typedef Type result_type;
0192
0193 template<typename ChainedPtr>
0194
0195 #if !defined(BOOST_NO_SFINAE)
0196 typename disable_if<
0197 is_convertible<const ChainedPtr&,const Class&>,Type&>::type
0198 #else
0199 Type&
0200 #endif
0201
0202 operator()(const ChainedPtr& x)const
0203 {
0204 return operator()(*x);
0205 }
0206
0207 const Type& operator()(const Class& x)const
0208 {
0209 return *static_cast<const Type*>(
0210 static_cast<const void*>(
0211 static_cast<const char*>(
0212 static_cast<const void *>(&x))+OffsetOfMember));
0213 }
0214
0215 Type& operator()(Class& x)const
0216 {
0217 return *static_cast<Type*>(
0218 static_cast<void*>(
0219 static_cast<char*>(static_cast<void *>(&x))+OffsetOfMember));
0220 }
0221
0222 const Type& operator()(const reference_wrapper<const Class>& x)const
0223 {
0224 return operator()(x.get());
0225 }
0226
0227 Type& operator()(const reference_wrapper<Class>& x)const
0228 {
0229 return operator()(x.get());
0230 }
0231 };
0232
0233 }
0234
0235 template<class Class,typename Type,std::size_t OffsetOfMember>
0236 struct member_offset:
0237 mpl::if_c<
0238 is_const<Type>::value,
0239 detail::const_member_offset_base<Class,Type,OffsetOfMember>,
0240 detail::non_const_member_offset_base<Class,Type,OffsetOfMember>
0241 >::type
0242 {
0243 };
0244
0245
0246
0247
0248
0249
0250 #if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS)
0251 #define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \
0252 ::boost::multi_index::member_offset< Class,Type,offsetof(Class,MemberName) >
0253 #else
0254 #define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \
0255 ::boost::multi_index::member< Class,Type,&Class::MemberName >
0256 #endif
0257
0258 }
0259
0260 }
0261
0262 #endif