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
28namespace boost{
29
30template<class Type> class reference_wrapper; /* fwd decl. */
31
32namespace multi_index{
33
34namespace 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
46template<typename Type>
47struct 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
59 operator()(const ChainedPtr& x)const
60 {
61 return operator()(*x);
62 }
63
64 Type& operator()(Type& x)const
65 {
66 return x;
67 }
68
69 Type& operator()(const reference_wrapper<Type>& x)const
70 {
71 return x.get();
72 }
73
74 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
88template<typename Type>
89struct 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
104 operator()(const ChainedPtr& x)const
105 {
106 return operator()(*x);
107 }
108
109 const Type& operator()(const Type& x)const
110 {
111 return x;
112 }
113
114 Type& operator()(Type& x)const
115 {
116 return x;
117 }
118
119 const Type& operator()(const reference_wrapper<const Type>& x)const
120 {
121 return x.get();
122 }
123
124 Type& operator()(const reference_wrapper<Type>& x)const
125 {
126 return x.get();
127 }
128};
129
130} /* namespace multi_index::detail */
131
132template<class Type>
133struct 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

source code of boost/boost/multi_index/identity.hpp