1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/epoc32/include/stdapis/boost/multi_index/member.hpp Tue Mar 16 16:12:26 2010 +0000
1.3 @@ -0,0 +1,269 @@
1.4 +/* Copyright 2003-2006 Joaquín M López Muñoz.
1.5 + * Distributed under the Boost Software License, Version 1.0.
1.6 + * (See accompanying file LICENSE_1_0.txt or copy at
1.7 + * http://www.boost.org/LICENSE_1_0.txt)
1.8 + *
1.9 + * See http://www.boost.org/libs/multi_index for library home page.
1.10 + */
1.11 +
1.12 +#ifndef BOOST_MULTI_INDEX_MEMBER_HPP
1.13 +#define BOOST_MULTI_INDEX_MEMBER_HPP
1.14 +
1.15 +#if defined(_MSC_VER)&&(_MSC_VER>=1200)
1.16 +#pragma once
1.17 +#endif
1.18 +
1.19 +#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
1.20 +#include <boost/mpl/if.hpp>
1.21 +#include <boost/type_traits/is_const.hpp>
1.22 +#include <boost/utility/enable_if.hpp>
1.23 +#include <cstddef>
1.24 +
1.25 +#if !defined(BOOST_NO_SFINAE)
1.26 +#include <boost/type_traits/is_convertible.hpp>
1.27 +#endif
1.28 +
1.29 +namespace boost{
1.30 +
1.31 +template<class T> class reference_wrapper; /* fwd decl. */
1.32 +
1.33 +namespace multi_index{
1.34 +
1.35 +namespace detail{
1.36 +
1.37 +/* member is a read/write key extractor for accessing a given
1.38 + * member of a class.
1.39 + * Additionally, member is overloaded to support referece_wrappers
1.40 + * of T and "chained pointers" to T's. By chained pointer to T we mean
1.41 + * a type P such that, given a p of Type P
1.42 + * *...n...*x is convertible to T&, for some n>=1.
1.43 + * Examples of chained pointers are raw and smart pointers, iterators and
1.44 + * arbitrary combinations of these (vg. T** or auto_ptr<T*>.)
1.45 + */
1.46 +
1.47 +/* NB. Some overloads of operator() have an extra dummy parameter int=0.
1.48 + * This disambiguator serves several purposes:
1.49 + * - Without it, MSVC++ 6.0 incorrectly regards some overloads as
1.50 + * specializations of a previous member function template.
1.51 + * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
1.52 + * as if they have the same signature.
1.53 + * - If remove_const is broken due to lack of PTS, int=0 avoids the
1.54 + * declaration of memfuns with identical signature.
1.55 + */
1.56 +
1.57 +template<class Class,typename Type,Type Class::*PtrToMember>
1.58 +struct const_member_base
1.59 +{
1.60 + typedef Type result_type;
1.61 +
1.62 + template<typename ChainedPtr>
1.63 +
1.64 +#if !defined(BOOST_NO_SFINAE)
1.65 + typename disable_if<
1.66 + is_convertible<const ChainedPtr&,const Class&>,Type&>::type
1.67 +#else
1.68 + Type&
1.69 +#endif
1.70 +
1.71 + operator()(const ChainedPtr& x)const
1.72 + {
1.73 + return operator()(*x);
1.74 + }
1.75 +
1.76 + Type& operator()(const Class& x)const
1.77 + {
1.78 + return x.*PtrToMember;
1.79 + }
1.80 +
1.81 + Type& operator()(const reference_wrapper<const Class>& x)const
1.82 + {
1.83 + return operator()(x.get());
1.84 + }
1.85 +
1.86 + Type& operator()(const reference_wrapper<Class>& x,int=0)const
1.87 + {
1.88 + return operator()(x.get());
1.89 + }
1.90 +};
1.91 +
1.92 +template<class Class,typename Type,Type Class::*PtrToMember>
1.93 +struct non_const_member_base
1.94 +{
1.95 + typedef Type result_type;
1.96 +
1.97 + template<typename ChainedPtr>
1.98 +
1.99 +#if !defined(BOOST_NO_SFINAE)
1.100 + typename disable_if<
1.101 + is_convertible<const ChainedPtr&,const Class&>,Type&>::type
1.102 +#else
1.103 + Type&
1.104 +#endif
1.105 +
1.106 + operator()(const ChainedPtr& x)const
1.107 + {
1.108 + return operator()(*x);
1.109 + }
1.110 +
1.111 + const Type& operator()(const Class& x,int=0)const
1.112 + {
1.113 + return x.*PtrToMember;
1.114 + }
1.115 +
1.116 + Type& operator()(Class& x)const
1.117 + {
1.118 + return x.*PtrToMember;
1.119 + }
1.120 +
1.121 + const Type& operator()(const reference_wrapper<const Class>& x,int=0)const
1.122 + {
1.123 + return operator()(x.get());
1.124 + }
1.125 +
1.126 + Type& operator()(const reference_wrapper<Class>& x)const
1.127 + {
1.128 + return operator()(x.get());
1.129 + }
1.130 +};
1.131 +
1.132 +} /* namespace multi_index::detail */
1.133 +
1.134 +template<class Class,typename Type,Type Class::*PtrToMember>
1.135 +struct member:
1.136 + mpl::if_c<
1.137 + is_const<Type>::value,
1.138 + detail::const_member_base<Class,Type,PtrToMember>,
1.139 + detail::non_const_member_base<Class,Type,PtrToMember>
1.140 + >::type
1.141 +{
1.142 +};
1.143 +
1.144 +namespace detail{
1.145 +
1.146 +/* MSVC++ 6.0 does not support properly pointers to members as
1.147 + * non-type template arguments, as reported in
1.148 + * http://support.microsoft.com/default.aspx?scid=kb;EN-US;249045
1.149 + * A similar problem (though not identical) is shown by MSVC++ 7.0.
1.150 + * We provide an alternative to member<> accepting offsets instead
1.151 + * of pointers to members. This happens to work even for non-POD
1.152 + * types (although the standard forbids use of offsetof on these),
1.153 + * so it serves as a workaround in this compiler for all practical
1.154 + * purposes.
1.155 + * Surprisingly enough, other compilers, like Intel C++ 7.0/7.1 and
1.156 + * Visual Age 6.0, have similar bugs. This replacement of member<>
1.157 + * can be used for them too.
1.158 + */
1.159 +
1.160 +template<class Class,typename Type,std::size_t OffsetOfMember>
1.161 +struct const_member_offset_base
1.162 +{
1.163 + typedef Type result_type;
1.164 +
1.165 + template<typename ChainedPtr>
1.166 +
1.167 +#if !defined(BOOST_NO_SFINAE)
1.168 + typename disable_if<
1.169 + is_convertible<const ChainedPtr&,const Class&>,Type&>::type
1.170 +#else
1.171 + Type&
1.172 +#endif
1.173 +
1.174 + operator()(const ChainedPtr& x)const
1.175 + {
1.176 + return operator()(*x);
1.177 + }
1.178 +
1.179 + Type& operator()(const Class& x)const
1.180 + {
1.181 + return *static_cast<const Type*>(
1.182 + static_cast<const void*>(
1.183 + static_cast<const char*>(
1.184 + static_cast<const void *>(&x))+OffsetOfMember));
1.185 + }
1.186 +
1.187 + Type& operator()(const reference_wrapper<const Class>& x)const
1.188 + {
1.189 + return operator()(x.get());
1.190 + }
1.191 +
1.192 + Type& operator()(const reference_wrapper<Class>& x,int=0)const
1.193 + {
1.194 + return operator()(x.get());
1.195 + }
1.196 +};
1.197 +
1.198 +template<class Class,typename Type,std::size_t OffsetOfMember>
1.199 +struct non_const_member_offset_base
1.200 +{
1.201 + typedef Type result_type;
1.202 +
1.203 + template<typename ChainedPtr>
1.204 +
1.205 +#if !defined(BOOST_NO_SFINAE)
1.206 + typename disable_if<
1.207 + is_convertible<const ChainedPtr&,const Class&>,Type&>::type
1.208 +#else
1.209 + Type&
1.210 +#endif
1.211 +
1.212 + operator()(const ChainedPtr& x)const
1.213 + {
1.214 + return operator()(*x);
1.215 + }
1.216 +
1.217 + const Type& operator()(const Class& x,int=0)const
1.218 + {
1.219 + return *static_cast<const Type*>(
1.220 + static_cast<const void*>(
1.221 + static_cast<const char*>(
1.222 + static_cast<const void *>(&x))+OffsetOfMember));
1.223 + }
1.224 +
1.225 + Type& operator()(Class& x)const
1.226 + {
1.227 + return *static_cast<Type*>(
1.228 + static_cast<void*>(
1.229 + static_cast<char*>(static_cast<void *>(&x))+OffsetOfMember));
1.230 + }
1.231 +
1.232 + const Type& operator()(const reference_wrapper<const Class>& x,int=0)const
1.233 + {
1.234 + return operator()(x.get());
1.235 + }
1.236 +
1.237 + Type& operator()(const reference_wrapper<Class>& x)const
1.238 + {
1.239 + return operator()(x.get());
1.240 + }
1.241 +};
1.242 +
1.243 +} /* namespace multi_index::detail */
1.244 +
1.245 +template<class Class,typename Type,std::size_t OffsetOfMember>
1.246 +struct member_offset:
1.247 + mpl::if_c<
1.248 + is_const<Type>::value,
1.249 + detail::const_member_offset_base<Class,Type,OffsetOfMember>,
1.250 + detail::non_const_member_offset_base<Class,Type,OffsetOfMember>
1.251 + >::type
1.252 +{
1.253 +};
1.254 +
1.255 +/* BOOST_MULTI_INDEX_MEMBER resolves to member in the normal cases,
1.256 + * and to member_offset as a workaround in those defective compilers for
1.257 + * which BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS is defined.
1.258 + */
1.259 +
1.260 +#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS)
1.261 +#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \
1.262 +::boost::multi_index::member_offset< Class,Type,offsetof(Class,MemberName) >
1.263 +#else
1.264 +#define BOOST_MULTI_INDEX_MEMBER(Class,Type,MemberName) \
1.265 +::boost::multi_index::member< Class,Type,&Class::MemberName >
1.266 +#endif
1.267 +
1.268 +} /* namespace multi_index */
1.269 +
1.270 +} /* namespace boost */
1.271 +
1.272 +#endif