• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
9 #ifndef BOOST_MULTI_INDEX_IDENTITY_HPP
10 #define BOOST_MULTI_INDEX_IDENTITY_HPP
11 
12 #if defined(_MSC_VER)
13 #pragma once
14 #endif
15 
16 #include <boost/config.hpp>
17 #include <boost/detail/workaround.hpp>
18 #include <boost/mpl/if.hpp>
19 #include <boost/multi_index/identity_fwd.hpp>
20 #include <boost/type_traits/is_const.hpp>
21 #include <boost/type_traits/remove_const.hpp>
22 #include <boost/utility/enable_if.hpp>
23 
24 #if !defined(BOOST_NO_SFINAE)
25 #include <boost/type_traits/is_convertible.hpp>
26 #endif
27 
28 namespace boost{
29 
30 template<class Type> class reference_wrapper; /* fwd decl. */
31 
32 namespace multi_index{
33 
34 namespace detail{
35 
36 /* identity is a do-nothing key extractor that returns the [const] Type&
37  * object passed.
38  * Additionally, identity is overloaded to support referece_wrappers
39  * of Type and "chained pointers" to Type's. By chained pointer to Type we
40  * mean a  type  P such that, given a p of type P
41  *   *...n...*x is convertible to Type&, for some n>=1.
42  * Examples of chained pointers are raw and smart pointers, iterators and
43  * arbitrary combinations of these (vg. Type** or unique_ptr<Type*>.)
44  */
45 
46 template<typename Type>
47 struct const_identity_base
48 {
49   typedef Type result_type;
50 
51   template<typename ChainedPtr>
52 
53 #if !defined(BOOST_NO_SFINAE)
54   typename disable_if<is_convertible<const ChainedPtr&,Type&>,Type&>::type
55 #else
56   Type&
57 #endif
58 
operator ()boost::multi_index::detail::const_identity_base59   operator()(const ChainedPtr& x)const
60   {
61     return operator()(*x);
62   }
63 
operator ()boost::multi_index::detail::const_identity_base64   Type& operator()(Type& x)const
65   {
66     return x;
67   }
68 
operator ()boost::multi_index::detail::const_identity_base69   Type& operator()(const reference_wrapper<Type>& x)const
70   {
71     return x.get();
72   }
73 
operator ()boost::multi_index::detail::const_identity_base74   Type& operator()(
75     const reference_wrapper<typename remove_const<Type>::type>& x
76 
77 #if BOOST_WORKAROUND(BOOST_MSVC,==1310)
78 /* http://lists.boost.org/Archives/boost/2015/10/226135.php */
79     ,int=0
80 #endif
81 
82   )const
83   {
84     return x.get();
85   }
86 };
87 
88 template<typename Type>
89 struct non_const_identity_base
90 {
91   typedef Type result_type;
92 
93   /* templatized for pointer-like types */
94 
95   template<typename ChainedPtr>
96 
97 #if !defined(BOOST_NO_SFINAE)
98   typename disable_if<
99     is_convertible<const ChainedPtr&,const Type&>,Type&>::type
100 #else
101   Type&
102 #endif
103 
operator ()boost::multi_index::detail::non_const_identity_base104   operator()(const ChainedPtr& x)const
105   {
106     return operator()(*x);
107   }
108 
operator ()boost::multi_index::detail::non_const_identity_base109   const Type& operator()(const Type& x)const
110   {
111     return x;
112   }
113 
operator ()boost::multi_index::detail::non_const_identity_base114   Type& operator()(Type& x)const
115   {
116     return x;
117   }
118 
operator ()boost::multi_index::detail::non_const_identity_base119   const Type& operator()(const reference_wrapper<const Type>& x)const
120   {
121     return x.get();
122   }
123 
operator ()boost::multi_index::detail::non_const_identity_base124   Type& operator()(const reference_wrapper<Type>& x)const
125   {
126     return x.get();
127   }
128 };
129 
130 } /* namespace multi_index::detail */
131 
132 template<class Type>
133 struct identity:
134   mpl::if_c<
135     is_const<Type>::value,
136     detail::const_identity_base<Type>,detail::non_const_identity_base<Type>
137   >::type
138 {
139 };
140 
141 } /* namespace multi_index */
142 
143 } /* namespace boost */
144 
145 #endif
146