/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. #ifndef BOOST_MULTI_INDEX_IDENTITY_HPP
  9. #define BOOST_MULTI_INDEX_IDENTITY_HPP
  10. #if defined(_MSC_VER)&&(_MSC_VER>=1200)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp>
  14. #include <boost/mpl/if.hpp>
  15. #include <boost/multi_index/identity_fwd.hpp>
  16. #include <boost/type_traits/is_const.hpp>
  17. #include <boost/type_traits/remove_const.hpp>
  18. #include <boost/utility/enable_if.hpp>
  19. #if !defined(BOOST_NO_SFINAE)
  20. #include <boost/type_traits/is_convertible.hpp>
  21. #endif
  22. namespace boost{
  23. template<class Type> class reference_wrapper; /* fwd decl. */
  24. namespace multi_index{
  25. namespace detail{
  26. /* identity is a do-nothing key extractor that returns the [const] Type&
  27. * object passed.
  28. * Additionally, identity is overloaded to support referece_wrappers
  29. * of Type and "chained pointers" to Type's. By chained pointer to Type we
  30. * mean a type P such that, given a p of type P
  31. * *...n...*x is convertible to Type&, for some n>=1.
  32. * Examples of chained pointers are raw and smart pointers, iterators and
  33. * arbitrary combinations of these (vg. Type** or auto_ptr<Type*>.)
  34. */
  35. /* NB. Some overloads of operator() have an extra dummy parameter int=0.
  36. * This disambiguator serves several purposes:
  37. * - Without it, MSVC++ 6.0 incorrectly regards some overloads as
  38. * specializations of a previous member function template.
  39. * - MSVC++ 6.0/7.0 seem to incorrectly treat some different memfuns
  40. * as if they have the same signature.
  41. * - If remove_const is broken due to lack of PTS, int=0 avoids the
  42. * declaration of memfuns with identical signature.
  43. */
  44. template<typename Type>
  45. struct const_identity_base
  46. {
  47. typedef Type result_type;
  48. template<typename ChainedPtr>
  49. #if !defined(BOOST_NO_SFINAE)
  50. typename disable_if<is_convertible<const ChainedPtr&,Type&>,Type&>::type
  51. #else
  52. Type&
  53. #endif
  54. operator()(const ChainedPtr& x)const
  55. {
  56. return operator()(*x);
  57. }
  58. Type& operator()(Type& x)const
  59. {
  60. return x;
  61. }
  62. Type& operator()(const reference_wrapper<Type>& x)const
  63. {
  64. return x.get();
  65. }
  66. Type& operator()(
  67. const reference_wrapper<typename remove_const<Type>::type>& x,int=0)const
  68. {
  69. return x.get();
  70. }
  71. };
  72. template<typename Type>
  73. struct non_const_identity_base
  74. {
  75. typedef Type result_type;
  76. /* templatized for pointer-like types */
  77. template<typename ChainedPtr>
  78. #if !defined(BOOST_NO_SFINAE)
  79. typename disable_if<
  80. is_convertible<const ChainedPtr&,const Type&>,Type&>::type
  81. #else
  82. Type&
  83. #endif
  84. operator()(const ChainedPtr& x)const
  85. {
  86. return operator()(*x);
  87. }
  88. const Type& operator()(const Type& x,int=0)const
  89. {
  90. return x;
  91. }
  92. Type& operator()(Type& x)const
  93. {
  94. return x;
  95. }
  96. const Type& operator()(const reference_wrapper<const Type>& x,int=0)const
  97. {
  98. return x.get();
  99. }
  100. Type& operator()(const reference_wrapper<Type>& x)const
  101. {
  102. return x.get();
  103. }
  104. };
  105. } /* namespace multi_index::detail */
  106. template<class Type>
  107. struct identity:
  108. mpl::if_c<
  109. is_const<Type>::value,
  110. detail::const_identity_base<Type>,detail::non_const_identity_base<Type>
  111. >::type
  112. {
  113. };
  114. } /* namespace multi_index */
  115. } /* namespace boost */
  116. #endif