1 // Boost.Bimap 2 // 3 // Copyright (c) 2006-2007 Matias Capeletto 4 // 5 // Distributed under the Boost Software License, Version 1.0. 6 // (See accompanying file LICENSE_1_0.txt or copy at 7 // http://www.boost.org/LICENSE_1_0.txt) 8 9 /// \file unordered_multiset_of.hpp 10 /// \brief Include support for unordered_multiset constrains for the bimap container 11 12 #ifndef BOOST_BIMAP_UNORDERED_MULTISET_OF_HPP 13 #define BOOST_BIMAP_UNORDERED_MULTISET_OF_HPP 14 15 #if defined(_MSC_VER) 16 #pragma once 17 #endif 18 19 #include <boost/config.hpp> 20 21 #include <boost/bimap/detail/user_interface_config.hpp> 22 23 #include <cstdlib> 24 #include <functional> 25 #include <boost/functional/hash.hpp> 26 #include <boost/mpl/bool.hpp> 27 28 #include <boost/concept_check.hpp> 29 30 #include <boost/bimap/detail/concept_tags.hpp> 31 32 #include <boost/bimap/tags/support/value_type_of.hpp> 33 34 #include <boost/bimap/detail/generate_index_binder.hpp> 35 #include <boost/bimap/detail/generate_view_binder.hpp> 36 #include <boost/bimap/detail/generate_relation_binder.hpp> 37 38 #include <boost/multi_index/hashed_index.hpp> 39 40 #include <boost/bimap/views/unordered_multimap_view.hpp> 41 #include <boost/bimap/views/unordered_multiset_view.hpp> 42 43 namespace boost { 44 namespace bimaps { 45 46 47 /// \brief Set Type Specification 48 /** 49 This struct is used to specify an unordered_multiset specification. 50 It is not a container, it is just a metaprogramming facility to 51 express the type of a set. Generally, this specification will 52 be used in other place to create a container. 53 It has the same syntax that an tr1::unordered_multiset instantiation, 54 except that the allocator cannot be specified. The rationale behind 55 this difference is that the allocator is not part of the 56 unordered_multiset type specification, rather it is a container 57 configuration parameter. 58 The first parameter is the type of the objects in the set, the 59 second one is a Hash Functor that takes objects of this type, and 60 the third one is a Functor that compares them for equality. 61 Bimap binding metafunctions can be used with this class in 62 the following way: 63 64 \code 65 using namespace support; 66 67 BOOST_STATIC_ASSERT( is_set_type_of< unordered_multiset_of<Type> >::value ) 68 69 BOOST_STATIC_ASSERT 70 ( 71 is_same 72 < 73 compute_index_type 74 < 75 unordered_multiset_of<Type,HashFunctor,EqualKey>, 76 KeyExtractor, 77 Tag 78 79 >::type 80 , 81 hashed_nonunique< tag<Tag>, KeyExtractor, HashFunctor, EqualKey > 82 83 >::value 84 ) 85 86 typedef bimap 87 < 88 unordered_multiset_of<Type>, RightKeyType 89 90 > bimap_with_left_type_as_unordered_multiset; 91 92 BOOST_STATIC_ASSERT 93 ( 94 is_same 95 < 96 compute_map_view_type 97 < 98 member_at::left, 99 bimap_with_left_type_as_unordered_multiset 100 101 >::type, 102 103 unordered_multimap_view 104 < 105 member_at::left, 106 bimap_with_left_type_as_unordered_multiset 107 > 108 109 >::value 110 ) 111 112 \endcode 113 114 See also unordered_multiset_of_relation. 115 **/ 116 117 template 118 < 119 class KeyType, 120 class HashFunctor = hash< BOOST_DEDUCED_TYPENAME 121 ::boost::bimaps::tags::support::value_type_of<KeyType>::type >, 122 class EqualKey = std::equal_to< BOOST_DEDUCED_TYPENAME 123 ::boost::bimaps::tags::support::value_type_of<KeyType>::type > 124 > 125 struct unordered_multiset_of : public ::boost::bimaps::detail::set_type_of_tag 126 { 127 /// User type, can be tagged 128 typedef KeyType user_type; 129 130 /// Type of the object that will be stored in the container 131 typedef BOOST_DEDUCED_TYPENAME ::boost::bimaps::tags::support:: 132 value_type_of<user_type>::type value_type; 133 134 /// Hash Functor that takes value_type objects 135 typedef HashFunctor hasher; 136 137 /// Functor that compare two value_type objects for equality 138 typedef EqualKey key_equal; 139 140 struct lazy_concept_checked 141 { 142 BOOST_CLASS_REQUIRE ( value_type, 143 boost, AssignableConcept ); 144 145 BOOST_CLASS_REQUIRE3( hasher, std::size_t, value_type, 146 boost, UnaryFunctionConcept ); 147 148 BOOST_CLASS_REQUIRE4( key_equal, bool, value_type, value_type, 149 boost, BinaryFunctionConcept ); 150 151 typedef unordered_multiset_of type; 152 }; 153 154 BOOST_BIMAP_GENERATE_INDEX_BINDER_2CP( 155 156 // binds to 157 multi_index::hashed_non_unique, 158 159 // with 160 hasher, 161 key_equal 162 ) 163 164 BOOST_BIMAP_GENERATE_MAP_VIEW_BINDER( 165 166 // binds to 167 views::unordered_multimap_view 168 ) 169 170 BOOST_BIMAP_GENERATE_SET_VIEW_BINDER( 171 172 // binds to 173 views::unordered_multiset_view 174 ) 175 176 typedef mpl::bool_<false> mutable_key; 177 }; 178 179 180 /// \brief Set Of Relation Specification 181 /** 182 This struct is similar to unordered_multiset_of but it is bind logically 183 to a relation. It is used in the bimap instantiation to specify the 184 desired type of the main view. This struct implements internally 185 a metafunction named bind_to that manages the quite complicated 186 task of finding the right type of the set for the relation. 187 188 \code 189 template<class Relation> 190 struct bind_to 191 { 192 typedef -unspecified- type; 193 }; 194 \endcode 195 196 See also unordered_multiset_of, is_set_type_of_relation. 197 **/ 198 199 template 200 < 201 class HashFunctor = hash< _relation >, 202 class EqualKey = std::equal_to< _relation > 203 > 204 struct unordered_multiset_of_relation : public ::boost::bimaps::detail::set_type_of_relation_tag 205 { 206 /// Hash Functor that takes value_type objects 207 typedef HashFunctor hasher; 208 209 /// Functor that compare two value_type objects for equality 210 typedef EqualKey key_equal; 211 212 213 BOOST_BIMAP_GENERATE_RELATION_BINDER_2CP( 214 215 // binds to 216 unordered_multiset_of, 217 218 // with 219 hasher, 220 key_equal 221 ) 222 223 typedef mpl::bool_<false> left_mutable_key; 224 typedef mpl::bool_<false> right_mutable_key; 225 }; 226 227 228 } // namespace bimaps 229 } // namespace boost 230 231 232 #endif // BOOST_BIMAP_UNORDERED_MULTISET_OF_HPP 233 234