os/ossrv/ossrv_pub/boost_apis/boost/multi_index/identity.hpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* Copyright 2003-2006 Joaquín M López Muñoz.
sl@0
     2
 * Distributed under the Boost Software License, Version 1.0.
sl@0
     3
 * (See accompanying file LICENSE_1_0.txt or copy at
sl@0
     4
 * http://www.boost.org/LICENSE_1_0.txt)
sl@0
     5
 *
sl@0
     6
 * See http://www.boost.org/libs/multi_index for library home page.
sl@0
     7
 */
sl@0
     8
sl@0
     9
#ifndef BOOST_MULTI_INDEX_IDENTITY_HPP
sl@0
    10
#define BOOST_MULTI_INDEX_IDENTITY_HPP
sl@0
    11
sl@0
    12
#if defined(_MSC_VER)&&(_MSC_VER>=1200)
sl@0
    13
#pragma once
sl@0
    14
#endif
sl@0
    15
sl@0
    16
#include <boost/config.hpp>
sl@0
    17
#include <boost/mpl/if.hpp>
sl@0
    18
#include <boost/multi_index/identity_fwd.hpp>
sl@0
    19
#include <boost/type_traits/is_const.hpp>
sl@0
    20
#include <boost/type_traits/remove_const.hpp>
sl@0
    21
#include <boost/utility/enable_if.hpp>
sl@0
    22
sl@0
    23
#if !defined(BOOST_NO_SFINAE)
sl@0
    24
#include <boost/type_traits/is_convertible.hpp>
sl@0
    25
#endif
sl@0
    26
sl@0
    27
namespace boost{
sl@0
    28
sl@0
    29
template<class Type> class reference_wrapper; /* fwd decl. */
sl@0
    30
sl@0
    31
namespace multi_index{
sl@0
    32
sl@0
    33
namespace detail{
sl@0
    34
sl@0
    35
/* identity is a do-nothing key extractor that returns the [const] Type&
sl@0
    36
 * object passed.
sl@0
    37
 * Additionally, identity is overloaded to support referece_wrappers
sl@0
    38
 * of Type and "chained pointers" to Type's. By chained pointer to Type we
sl@0
    39
 * mean a  type  P such that, given a p of type P
sl@0
    40
 *   *...n...*x is convertible to Type&, for some n>=1.
sl@0
    41
 * Examples of chained pointers are raw and smart pointers, iterators and
sl@0
    42
 * arbitrary combinations of these (vg. Type** or auto_ptr<Type*>.)
sl@0
    43
 */
sl@0
    44
sl@0
    45
/* NB. Some overloads of operator() have an extra dummy parameter int=0.
sl@0
    46
 * This disambiguator serves several purposes:
sl@0
    47
 *  - Without it, MSVC++ 6.0 incorrectly regards some overloads as
sl@0
    48
 *    specializations of a previous member function template.
sl@0
    49
 *  - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
sl@0
    50
 *    as if they have the same signature.
sl@0
    51
 *  - If remove_const is broken due to lack of PTS, int=0 avoids the
sl@0
    52
 *    declaration of memfuns with identical signature.
sl@0
    53
 */
sl@0
    54
sl@0
    55
template<typename Type>
sl@0
    56
struct const_identity_base
sl@0
    57
{
sl@0
    58
  typedef Type result_type;
sl@0
    59
sl@0
    60
  template<typename ChainedPtr>
sl@0
    61
sl@0
    62
#if !defined(BOOST_NO_SFINAE)
sl@0
    63
  typename disable_if<is_convertible<const ChainedPtr&,Type&>,Type&>::type
sl@0
    64
#else
sl@0
    65
  Type&
sl@0
    66
#endif 
sl@0
    67
  
sl@0
    68
  operator()(const ChainedPtr& x)const
sl@0
    69
  {
sl@0
    70
    return operator()(*x);
sl@0
    71
  }
sl@0
    72
sl@0
    73
  Type& operator()(Type& x)const
sl@0
    74
  {
sl@0
    75
    return x;
sl@0
    76
  }
sl@0
    77
sl@0
    78
  Type& operator()(const reference_wrapper<Type>& x)const
sl@0
    79
  { 
sl@0
    80
    return x.get();
sl@0
    81
  }
sl@0
    82
sl@0
    83
  Type& operator()(
sl@0
    84
    const reference_wrapper<typename remove_const<Type>::type>& x,int=0)const
sl@0
    85
  { 
sl@0
    86
    return x.get();
sl@0
    87
  }
sl@0
    88
};
sl@0
    89
sl@0
    90
template<typename Type>
sl@0
    91
struct non_const_identity_base
sl@0
    92
{
sl@0
    93
  typedef Type result_type;
sl@0
    94
sl@0
    95
  /* templatized for pointer-like types */
sl@0
    96
  
sl@0
    97
  template<typename ChainedPtr>
sl@0
    98
sl@0
    99
#if !defined(BOOST_NO_SFINAE)
sl@0
   100
  typename disable_if<
sl@0
   101
    is_convertible<const ChainedPtr&,const Type&>,Type&>::type
sl@0
   102
#else
sl@0
   103
  Type&
sl@0
   104
#endif 
sl@0
   105
    
sl@0
   106
  operator()(const ChainedPtr& x)const
sl@0
   107
  {
sl@0
   108
    return operator()(*x);
sl@0
   109
  }
sl@0
   110
sl@0
   111
  const Type& operator()(const Type& x,int=0)const
sl@0
   112
  {
sl@0
   113
    return x;
sl@0
   114
  }
sl@0
   115
sl@0
   116
  Type& operator()(Type& x)const
sl@0
   117
  {
sl@0
   118
    return x;
sl@0
   119
  }
sl@0
   120
sl@0
   121
  const Type& operator()(const reference_wrapper<const Type>& x,int=0)const
sl@0
   122
  { 
sl@0
   123
    return x.get();
sl@0
   124
  }
sl@0
   125
sl@0
   126
  Type& operator()(const reference_wrapper<Type>& x)const
sl@0
   127
  { 
sl@0
   128
    return x.get();
sl@0
   129
  }
sl@0
   130
};
sl@0
   131
sl@0
   132
} /* namespace multi_index::detail */
sl@0
   133
sl@0
   134
template<class Type>
sl@0
   135
struct identity:
sl@0
   136
  mpl::if_c<
sl@0
   137
    is_const<Type>::value,
sl@0
   138
    detail::const_identity_base<Type>,detail::non_const_identity_base<Type>
sl@0
   139
  >::type
sl@0
   140
{
sl@0
   141
};
sl@0
   142
sl@0
   143
} /* namespace multi_index */
sl@0
   144
sl@0
   145
} /* namespace boost */
sl@0
   146
sl@0
   147
#endif