identity.hpp 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /* Copyright 2003-2015 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)
  11. #pragma once
  12. #endif
  13. #include <boost/config.hpp>
  14. #include <boost/detail/workaround.hpp>
  15. #include <boost/mpl/if.hpp>
  16. #include <boost/multi_index/identity_fwd.hpp>
  17. #include <boost/type_traits/is_const.hpp>
  18. #include <boost/type_traits/remove_const.hpp>
  19. #include <boost/utility/enable_if.hpp>
  20. #if !defined(BOOST_NO_SFINAE)
  21. #include <boost/type_traits/is_convertible.hpp>
  22. #endif
  23. namespace boost{
  24. template<class Type> class reference_wrapper; /* fwd decl. */
  25. namespace multi_index{
  26. namespace detail{
  27. /* identity is a do-nothing key extractor that returns the [const] Type&
  28. * object passed.
  29. * Additionally, identity is overloaded to support referece_wrappers
  30. * of Type and "chained pointers" to Type's. By chained pointer to Type we
  31. * mean a type P such that, given a p of type P
  32. * *...n...*x is convertible to Type&, for some n>=1.
  33. * Examples of chained pointers are raw and smart pointers, iterators and
  34. * arbitrary combinations of these (vg. Type** or unique_ptr<Type*>.)
  35. */
  36. template<typename Type>
  37. struct const_identity_base
  38. {
  39. typedef Type result_type;
  40. template<typename ChainedPtr>
  41. #if !defined(BOOST_NO_SFINAE)
  42. typename disable_if<is_convertible<const ChainedPtr&,Type&>,Type&>::type
  43. #else
  44. Type&
  45. #endif
  46. operator()(const ChainedPtr& x)const
  47. {
  48. return operator()(*x);
  49. }
  50. Type& operator()(Type& x)const
  51. {
  52. return x;
  53. }
  54. Type& operator()(const reference_wrapper<Type>& x)const
  55. {
  56. return x.get();
  57. }
  58. Type& operator()(
  59. const reference_wrapper<typename remove_const<Type>::type>& x
  60. #if BOOST_WORKAROUND(BOOST_MSVC,==1310)
  61. /* http://lists.boost.org/Archives/boost/2015/10/226135.php */
  62. ,int=0
  63. #endif
  64. )const
  65. {
  66. return x.get();
  67. }
  68. };
  69. template<typename Type>
  70. struct non_const_identity_base
  71. {
  72. typedef Type result_type;
  73. /* templatized for pointer-like types */
  74. template<typename ChainedPtr>
  75. #if !defined(BOOST_NO_SFINAE)
  76. typename disable_if<
  77. is_convertible<const ChainedPtr&,const Type&>,Type&>::type
  78. #else
  79. Type&
  80. #endif
  81. operator()(const ChainedPtr& x)const
  82. {
  83. return operator()(*x);
  84. }
  85. const Type& operator()(const Type& x)const
  86. {
  87. return x;
  88. }
  89. Type& operator()(Type& x)const
  90. {
  91. return x;
  92. }
  93. const Type& operator()(const reference_wrapper<const Type>& x)const
  94. {
  95. return x.get();
  96. }
  97. Type& operator()(const reference_wrapper<Type>& x)const
  98. {
  99. return x.get();
  100. }
  101. };
  102. } /* namespace multi_index::detail */
  103. template<class Type>
  104. struct identity:
  105. mpl::if_c<
  106. is_const<Type>::value,
  107. detail::const_identity_base<Type>,detail::non_const_identity_base<Type>
  108. >::type
  109. {
  110. };
  111. } /* namespace multi_index */
  112. } /* namespace boost */
  113. #endif