PageRenderTime 22ms CodeModel.GetById 15ms app.highlight 5ms RepoModel.GetById 1ms app.codeStats 0ms

/Src/Dependencies/Boost/boost/multi_index/identity.hpp

http://hadesmem.googlecode.com/
C++ Header | 147 lines | 90 code | 31 blank | 26 comment | 0 complexity | 16521f3016d8e47ded5a6c8cfd578455 MD5 | raw file
  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_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
 27namespace boost{
 28
 29template<class Type> class reference_wrapper; /* fwd decl. */
 30
 31namespace multi_index{
 32
 33namespace 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
 55template<typename Type>
 56struct 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
 90template<typename Type>
 91struct 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
134template<class Type>
135struct 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