File indexing completed on 2025-01-18 09:42:11
0001
0002
0003
0004
0005
0006
0007
0008
0009 #ifndef BOOST_MULTI_INDEX_KEY_HPP
0010 #define BOOST_MULTI_INDEX_KEY_HPP
0011
0012 #if defined(_MSC_VER)
0013 #pragma once
0014 #endif
0015
0016 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
0017 #include <boost/multi_index/composite_key.hpp>
0018 #include <boost/multi_index/global_fun.hpp>
0019 #include <boost/multi_index/member.hpp>
0020 #include <boost/multi_index/mem_fun.hpp>
0021
0022 #if __cplusplus>=201703L||\
0023 defined(BOOST_MSVC)&&defined(__cpp_nontype_template_parameter_auto)
0024
0025 #define BOOST_MULTI_INDEX_KEY_SUPPORTED
0026
0027 #include <boost/multi_index/detail/is_function.hpp>
0028 #include <boost/preprocessor/facilities/empty.hpp>
0029 #include <type_traits>
0030
0031 namespace boost{
0032
0033 namespace multi_index{
0034
0035
0036
0037 namespace detail{
0038
0039 template<typename T,T,typename=void>
0040 struct typed_key_impl;
0041
0042 template<typename Class,typename Type,Type Class::*PtrToMember>
0043 struct typed_key_impl<
0044 Type Class::*,PtrToMember,
0045 typename std::enable_if<!is_function<Type>::value>::type
0046 >
0047 {
0048 using value_type=Class;
0049 using type=member<Class,Type,PtrToMember>;
0050 };
0051
0052 #define BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(qualifier,extractor) \
0053 template< \
0054 typename Class,typename Type,Type (Class::*PtrToMemberFunction)()qualifier \
0055 > \
0056 struct typed_key_impl<Type (Class::*)()qualifier,PtrToMemberFunction> \
0057 { \
0058 using value_type=Class; \
0059 using type=extractor<Class,Type,PtrToMemberFunction>; \
0060 };
0061
0062 BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL( ,mem_fun)
0063 BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const ,const_mem_fun)
0064 BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(volatile ,volatile_mem_fun)
0065 BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const volatile ,cv_mem_fun)
0066 BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(& ,ref_mem_fun)
0067 BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const& ,cref_mem_fun)
0068 BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(volatile& ,vref_mem_fun)
0069 BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL(const volatile& ,cvref_mem_fun)
0070
0071 #undef BOOST_MULTI_INDEX_KEY_TYPED_KEY_IMPL
0072
0073 template<class Value,typename Type,Type (*PtrToFunction)(Value)>
0074 struct typed_key_impl<Type (*)(Value),PtrToFunction>
0075 {
0076 using value_type=Value;
0077 using type=global_fun<Value,Type,PtrToFunction>;
0078 };
0079
0080 template<typename T>
0081 struct remove_noexcept{using type=T;};
0082
0083 #define BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(qualifier) \
0084 template<typename R,typename C,typename... Args> \
0085 struct remove_noexcept<R(C::*)(Args...)qualifier noexcept> \
0086 {using type=R(C::*)(Args...)qualifier;}; \
0087 \
0088 template<typename R,typename C,typename... Args> \
0089 struct remove_noexcept<R(C::*)(Args...,...)qualifier noexcept> \
0090 {using type=R(C::*)(Args...,...)qualifier;};
0091
0092 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(BOOST_PP_EMPTY())
0093
0094 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const)
0095 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile)
0096 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile)
0097 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(&)
0098 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const&)
0099 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile&)
0100 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile&)
0101 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(&&)
0102 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const&&)
0103 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(volatile&&)
0104 BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT(const volatile&&)
0105
0106 #undef BOOST_MULTI_INDEX_KEY_REMOVE_MEMFUN_NOEXCEPT
0107
0108 template<typename R,typename... Args>
0109 struct remove_noexcept<R(*)(Args...)noexcept>{using type=R(*)(Args...);};
0110 template<typename R,typename... Args>
0111 struct remove_noexcept<R(*)(Args...,...)noexcept>
0112 {using type=R(*)(Args...,...);};
0113
0114 template<typename T>
0115 using remove_noexcept_t=typename remove_noexcept<T>::type;
0116
0117 template<auto... Keys>
0118 struct key_impl;
0119
0120 template<auto Key>
0121 struct key_impl<Key>:typed_key_impl<remove_noexcept_t<decltype(Key)>,Key>{};
0122
0123 template<typename... Ts>
0124 struct least_generic;
0125
0126 template<typename T0,typename... Ts>
0127 struct least_generic<T0,Ts...>
0128 {
0129 using type=T0;
0130 };
0131
0132 template<typename T0,typename T1,typename... Ts>
0133 struct least_generic<T0,T1,Ts...>
0134 {
0135 static_assert(
0136 std::is_convertible<const T0&,const T1&>::value||
0137 std::is_convertible<const T1&,const T0&>::value,
0138 "one type should be convertible to the other");
0139
0140 using type=typename least_generic<
0141 typename std::conditional<
0142 std::is_convertible<const T0&,const T1&>::value,T0,T1
0143 >::type,
0144 Ts...
0145 >::type;
0146 };
0147
0148 template<auto Key0,auto... Keys>
0149 struct key_impl<Key0,Keys...>
0150 {
0151 using value_type=typename least_generic<
0152 typename std::decay<typename key_impl<Key0>::value_type>::type,
0153 typename std::decay<typename key_impl<Keys>::value_type>::type...
0154 >::type;
0155 using type=composite_key<
0156 value_type,
0157 typename key_impl<Key0>::type,
0158 typename key_impl<Keys>::type...
0159 >;
0160 };
0161
0162 template<typename=composite_key<void,void>>
0163 struct composite_key_size;
0164
0165 template<typename... Args>
0166 struct composite_key_size<composite_key<Args...>>
0167 {
0168 static constexpr auto value=sizeof...(Args)-1;
0169 };
0170
0171 template<auto... Keys>
0172 struct limited_size_key_impl
0173 {
0174 static_assert(
0175 sizeof...(Keys)<=composite_key_size<>::value,
0176 "specified number of keys must meet the limits of "
0177 "boost::multi_index::composite_key");
0178 using type=typename key_impl<Keys...>::type;
0179 };
0180
0181 }
0182
0183 template<auto... Keys>
0184 using key=typename detail::limited_size_key_impl<Keys...>::type;
0185
0186 }
0187
0188 }
0189
0190 #endif
0191 #endif