Line data Source code
1 : /* Copyright 2003-2022 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/core/enable_if.hpp> 18 : #include <boost/detail/workaround.hpp> 19 : #include <boost/mpl/if.hpp> 20 : #include <boost/multi_index/identity_fwd.hpp> 21 : #include <boost/type_traits/is_const.hpp> 22 : #include <boost/type_traits/remove_const.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 : 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 : 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 : 104 : operator()(const ChainedPtr& x)const 105 : { 106 : return operator()(*x); 107 : } 108 : 109 7158576 : const Type& operator()(const Type& x)const 110 : { 111 7158576 : return x; 112 : } 113 : 114 21664969 : Type& operator()(Type& x)const 115 : { 116 21664969 : 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 : 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