1 /* Copyright 2003-2013 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_DETAIL_HASH_INDEX_ARGS_HPP 10 #define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ARGS_HPP 11 12 #if defined(_MSC_VER) 13 #pragma once 14 #endif 15 16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */ 17 #include <boost/functional/hash.hpp> 18 #include <boost/mpl/aux_/na.hpp> 19 #include <boost/mpl/eval_if.hpp> 20 #include <boost/mpl/identity.hpp> 21 #include <boost/mpl/if.hpp> 22 #include <boost/multi_index/tag.hpp> 23 #include <boost/static_assert.hpp> 24 #include <boost/type_traits/is_same.hpp> 25 #include <functional> 26 27 namespace boost{ 28 29 namespace multi_index{ 30 31 namespace detail{ 32 33 /* Hashed index specifiers can be instantiated in two forms: 34 * 35 * (hashed_unique|hashed_non_unique)< 36 * KeyFromValue, 37 * Hash=boost::hash<KeyFromValue::result_type>, 38 * Pred=std::equal_to<KeyFromValue::result_type> > 39 * (hashed_unique|hashed_non_unique)< 40 * TagList, 41 * KeyFromValue, 42 * Hash=boost::hash<KeyFromValue::result_type>, 43 * Pred=std::equal_to<KeyFromValue::result_type> > 44 * 45 * hashed_index_args implements the machinery to accept this 46 * argument-dependent polymorphism. 47 */ 48 49 template<typename KeyFromValue> 50 struct index_args_default_hash 51 { 52 typedef ::boost::hash<typename KeyFromValue::result_type> type; 53 }; 54 55 template<typename KeyFromValue> 56 struct index_args_default_pred 57 { 58 typedef std::equal_to<typename KeyFromValue::result_type> type; 59 }; 60 61 template<typename Arg1,typename Arg2,typename Arg3,typename Arg4> 62 struct hashed_index_args 63 { 64 typedef is_tag<Arg1> full_form; 65 66 typedef typename mpl::if_< 67 full_form, 68 Arg1, 69 tag< > >::type tag_list_type; 70 typedef typename mpl::if_< 71 full_form, 72 Arg2, 73 Arg1>::type key_from_value_type; 74 typedef typename mpl::if_< 75 full_form, 76 Arg3, 77 Arg2>::type supplied_hash_type; 78 typedef typename mpl::eval_if< 79 mpl::is_na<supplied_hash_type>, 80 index_args_default_hash<key_from_value_type>, 81 mpl::identity<supplied_hash_type> 82 >::type hash_type; 83 typedef typename mpl::if_< 84 full_form, 85 Arg4, 86 Arg3>::type supplied_pred_type; 87 typedef typename mpl::eval_if< 88 mpl::is_na<supplied_pred_type>, 89 index_args_default_pred<key_from_value_type>, 90 mpl::identity<supplied_pred_type> 91 >::type pred_type; 92 93 BOOST_STATIC_ASSERT(is_tag<tag_list_type>::value); 94 BOOST_STATIC_ASSERT(!mpl::is_na<key_from_value_type>::value); 95 BOOST_STATIC_ASSERT(!mpl::is_na<hash_type>::value); 96 BOOST_STATIC_ASSERT(!mpl::is_na<pred_type>::value); 97 }; 98 99 } /* namespace multi_index::detail */ 100 101 } /* namespace multi_index */ 102 103 } /* namespace boost */ 104 105 #endif 106