Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:42:11

0001 /* Copyright 2003-2022 Joaquin M Lopez Munoz.
0002  * Distributed under the Boost Software License, Version 1.0.
0003  * (See accompanying file LICENSE_1_0.txt or copy at
0004  * http://www.boost.org/LICENSE_1_0.txt)
0005  *
0006  * See http://www.boost.org/libs/multi_index for library home page.
0007  */
0008 
0009 #ifndef BOOST_MULTI_INDEX_IDENTITY_HPP
0010 #define BOOST_MULTI_INDEX_IDENTITY_HPP
0011 
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015 
0016 #include <boost/config.hpp>
0017 #include <boost/core/enable_if.hpp>
0018 #include <boost/detail/workaround.hpp>
0019 #include <boost/mpl/if.hpp>
0020 #include <boost/multi_index/identity_fwd.hpp>
0021 #include <boost/type_traits/is_const.hpp>
0022 #include <boost/type_traits/remove_const.hpp>
0023 
0024 #if !defined(BOOST_NO_SFINAE)
0025 #include <boost/type_traits/is_convertible.hpp>
0026 #endif
0027 
0028 namespace boost{
0029 
0030 template<class Type> class reference_wrapper; /* fwd decl. */
0031 
0032 namespace multi_index{
0033 
0034 namespace detail{
0035 
0036 /* identity is a do-nothing key extractor that returns the [const] Type&
0037  * object passed.
0038  * Additionally, identity is overloaded to support referece_wrappers
0039  * of Type and "chained pointers" to Type's. By chained pointer to Type we
0040  * mean a  type  P such that, given a p of type P
0041  *   *...n...*x is convertible to Type&, for some n>=1.
0042  * Examples of chained pointers are raw and smart pointers, iterators and
0043  * arbitrary combinations of these (vg. Type** or unique_ptr<Type*>.)
0044  */
0045 
0046 template<typename Type>
0047 struct const_identity_base
0048 {
0049   typedef Type result_type;
0050 
0051   template<typename ChainedPtr>
0052 
0053 #if !defined(BOOST_NO_SFINAE)
0054   typename disable_if<is_convertible<const ChainedPtr&,Type&>,Type&>::type
0055 #else
0056   Type&
0057 #endif 
0058   
0059   operator()(const ChainedPtr& x)const
0060   {
0061     return operator()(*x);
0062   }
0063 
0064   Type& operator()(Type& x)const
0065   {
0066     return x;
0067   }
0068 
0069   Type& operator()(const reference_wrapper<Type>& x)const
0070   { 
0071     return x.get();
0072   }
0073 
0074   Type& operator()(
0075     const reference_wrapper<typename remove_const<Type>::type>& x
0076 
0077 #if BOOST_WORKAROUND(BOOST_MSVC,==1310)
0078 /* http://lists.boost.org/Archives/boost/2015/10/226135.php */
0079     ,int=0
0080 #endif
0081 
0082   )const
0083   { 
0084     return x.get();
0085   }
0086 };
0087 
0088 template<typename Type>
0089 struct non_const_identity_base
0090 {
0091   typedef Type result_type;
0092 
0093   /* templatized for pointer-like types */
0094   
0095   template<typename ChainedPtr>
0096 
0097 #if !defined(BOOST_NO_SFINAE)
0098   typename disable_if<
0099     is_convertible<const ChainedPtr&,const Type&>,Type&>::type
0100 #else
0101   Type&
0102 #endif 
0103     
0104   operator()(const ChainedPtr& x)const
0105   {
0106     return operator()(*x);
0107   }
0108 
0109   const Type& operator()(const Type& x)const
0110   {
0111     return x;
0112   }
0113 
0114   Type& operator()(Type& x)const
0115   {
0116     return x;
0117   }
0118 
0119   const Type& operator()(const reference_wrapper<const Type>& x)const
0120   { 
0121     return x.get();
0122   }
0123 
0124   Type& operator()(const reference_wrapper<Type>& x)const
0125   { 
0126     return x.get();
0127   }
0128 };
0129 
0130 } /* namespace multi_index::detail */
0131 
0132 template<class Type>
0133 struct identity:
0134   mpl::if_c<
0135     is_const<Type>::value,
0136     detail::const_identity_base<Type>,detail::non_const_identity_base<Type>
0137   >::type
0138 {
0139 };
0140 
0141 } /* namespace multi_index */
0142 
0143 } /* namespace boost */
0144 
0145 #endif