epoc32/include/stdapis/boost/multi_index/identity.hpp
author William Roberts <williamr@symbian.org>
Wed, 31 Mar 2010 12:33:34 +0100
branchSymbian3
changeset 4 837f303aceeb
permissions -rw-r--r--
Current Symbian^3 public API header files (from PDK 3.0.h)
This is the epoc32/include tree with the "platform" subtrees removed, and
all but a selected few mbg and rsg files removed.
     1 /* Copyright 2003-2006 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_IDENTITY_HPP
    10 #define BOOST_MULTI_INDEX_IDENTITY_HPP
    11 
    12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
    13 #pragma once
    14 #endif
    15 
    16 #include <boost/config.hpp>
    17 #include <boost/mpl/if.hpp>
    18 #include <boost/multi_index/identity_fwd.hpp>
    19 #include <boost/type_traits/is_const.hpp>
    20 #include <boost/type_traits/remove_const.hpp>
    21 #include <boost/utility/enable_if.hpp>
    22 
    23 #if !defined(BOOST_NO_SFINAE)
    24 #include <boost/type_traits/is_convertible.hpp>
    25 #endif
    26 
    27 namespace boost{
    28 
    29 template<class Type> class reference_wrapper; /* fwd decl. */
    30 
    31 namespace multi_index{
    32 
    33 namespace detail{
    34 
    35 /* identity is a do-nothing key extractor that returns the [const] Type&
    36  * object passed.
    37  * Additionally, identity is overloaded to support referece_wrappers
    38  * of Type and "chained pointers" to Type's. By chained pointer to Type we
    39  * mean a  type  P such that, given a p of type P
    40  *   *...n...*x is convertible to Type&, for some n>=1.
    41  * Examples of chained pointers are raw and smart pointers, iterators and
    42  * arbitrary combinations of these (vg. Type** or auto_ptr<Type*>.)
    43  */
    44 
    45 /* NB. Some overloads of operator() have an extra dummy parameter int=0.
    46  * This disambiguator serves several purposes:
    47  *  - Without it, MSVC++ 6.0 incorrectly regards some overloads as
    48  *    specializations of a previous member function template.
    49  *  - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
    50  *    as if they have the same signature.
    51  *  - If remove_const is broken due to lack of PTS, int=0 avoids the
    52  *    declaration of memfuns with identical signature.
    53  */
    54 
    55 template<typename Type>
    56 struct const_identity_base
    57 {
    58   typedef Type result_type;
    59 
    60   template<typename ChainedPtr>
    61 
    62 #if !defined(BOOST_NO_SFINAE)
    63   typename disable_if<is_convertible<const ChainedPtr&,Type&>,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()(Type& x)const
    74   {
    75     return x;
    76   }
    77 
    78   Type& operator()(const reference_wrapper<Type>& x)const
    79   { 
    80     return x.get();
    81   }
    82 
    83   Type& operator()(
    84     const reference_wrapper<typename remove_const<Type>::type>& x,int=0)const
    85   { 
    86     return x.get();
    87   }
    88 };
    89 
    90 template<typename Type>
    91 struct non_const_identity_base
    92 {
    93   typedef Type result_type;
    94 
    95   /* templatized for pointer-like types */
    96   
    97   template<typename ChainedPtr>
    98 
    99 #if !defined(BOOST_NO_SFINAE)
   100   typename disable_if<
   101     is_convertible<const ChainedPtr&,const Type&>,Type&>::type
   102 #else
   103   Type&
   104 #endif 
   105     
   106   operator()(const ChainedPtr& x)const
   107   {
   108     return operator()(*x);
   109   }
   110 
   111   const Type& operator()(const Type& x,int=0)const
   112   {
   113     return x;
   114   }
   115 
   116   Type& operator()(Type& x)const
   117   {
   118     return x;
   119   }
   120 
   121   const Type& operator()(const reference_wrapper<const Type>& x,int=0)const
   122   { 
   123     return x.get();
   124   }
   125 
   126   Type& operator()(const reference_wrapper<Type>& x)const
   127   { 
   128     return x.get();
   129   }
   130 };
   131 
   132 } /* namespace multi_index::detail */
   133 
   134 template<class Type>
   135 struct identity:
   136   mpl::if_c<
   137     is_const<Type>::value,
   138     detail::const_identity_base<Type>,detail::non_const_identity_base<Type>
   139   >::type
   140 {
   141 };
   142 
   143 } /* namespace multi_index */
   144 
   145 } /* namespace boost */
   146 
   147 #endif