Changeset 379ce989 in mainline
- Timestamp:
- 2018-07-05T21:41:21Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 99bf4c4
- Parents:
- f185504
- git-author:
- Dzejrou <dzejrou@…> (2018-04-25 21:00:16)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:21)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/unordered_map.hpp
rf185504 r379ce989 850 850 class Alloc = allocator<pair<const Key, Value>> 851 851 > 852 class unordered_multimap; 852 class unordered_multimap 853 { 854 public: 855 using key_type = Key; 856 using mapped_type = Value; 857 using value_type = pair<const key_type, mapped_type>; 858 using hasher = Hash; 859 using key_equal = Pred; 860 using allocator_type = Alloc; 861 using pointer = typename allocator_traits<allocator_type>::pointer; 862 using const_pointer = typename allocator_traits<allocator_type>::const_pointer; 863 using reference = value_type&; 864 using const_reference = const value_type&; 865 using size_type = size_t; 866 using difference_type = ptrdiff_t; 867 868 using iterator = aux::hash_table_iterator< 869 value_type, reference, pointer, size_type 870 >; 871 using const_iterator = aux::hash_table_const_iterator< 872 value_type, const_reference, const_pointer, size_type 873 >; 874 using local_iterator = aux::hash_table_local_iterator< 875 value_type, reference, pointer 876 >; 877 using const_local_iterator = aux::hash_table_const_local_iterator< 878 value_type, const_reference, const_pointer 879 >; 880 881 unordered_multimap() 882 : unordered_multimap{default_bucket_count_} 883 { /* DUMMY BODY */ } 884 885 explicit unordered_multimap(size_type bucket_count, 886 const hasher& hf = hasher{}, 887 const key_equal& eql = key_equal{}, 888 const allocator_type& alloc = allocator_type{}) 889 : table_{bucket_count, hf, eql}, allocator_{alloc} 890 { /* DUMMY BODY */ } 891 892 template<class InputIterator> 893 unordered_multimap(InputIterator first, InputIterator last, 894 size_type bucket_count = default_bucket_count_, 895 const hasher& hf = hasher{}, 896 const key_equal& eql = key_equal{}, 897 const allocator_type& alloc = allocator_type{}) 898 : unordered_multimap{bucket_count, hf, eql, alloc} 899 { 900 insert(first, last); 901 } 902 903 unordered_multimap(const unordered_multimap& other) 904 : unordered_multimap{other, other.allocator_} 905 { /* DUMMY BODY */ } 906 907 unordered_multimap(unordered_multimap&& other) 908 : table_{move(other.table_)}, allocator_{move(other.allocator_)} 909 { /* DUMMY BODY */ } 910 911 explicit unordered_multimap(const allocator_type& alloc) 912 : table_{default_bucket_count_}, allocator_{alloc} 913 { /* DUMMY BODY */ } 914 915 unordered_multimap(const unordered_multimap& other, const allocator_type& alloc) 916 : table_{other.table_}, allocator_{alloc} 917 { /* DUMMY BODY */ } 918 919 unordered_multimap(unordered_multimap&& other, const allocator_type& alloc) 920 : table_{move(other.table_)}, allocator_{alloc} 921 { /* DUMMY BODY */ } 922 923 unordered_multimap(initializer_list<value_type> init, 924 size_type bucket_count = default_bucket_count_, 925 const hasher& hf = hasher{}, 926 const key_equal& eql = key_equal{}, 927 const allocator_type& alloc = allocator_type{}) 928 : unordered_multimap{bucket_count, hf, eql, alloc} 929 { 930 insert(init.begin(), init.end()); 931 } 932 933 unordered_multimap(size_type bucket_count, const allocator_type& alloc) 934 : unordered_multimap{bucket_count, hasher{}, key_equal{}, alloc} 935 { /* DUMMY BODY */ } 936 937 unordered_multimap(size_type bucket_count, const hasher& hf, const allocator_type& alloc) 938 : unordered_multimap{bucket_count, hf, key_equal{}, alloc} 939 { /* DUMMY BODY */ } 940 941 template<class InputIterator> 942 unordered_multimap(InputIterator first, InputIterator last, 943 size_type bucket_count, const allocator_type& alloc) 944 : unordered_multimap{first, last, bucket_count, hasher{}, key_equal{}, alloc} 945 { /* DUMMY BODY */ } 946 947 template<class InputIterator> 948 unordered_multimap(InputIterator first, InputIterator last, 949 size_type bucket_count, const hasher& hf, const allocator_type& alloc) 950 : unordered_multimap{first, last, bucket_count, hf, key_equal{}, alloc} 951 { /* DUMMY BODY */ } 952 953 unordered_multimap(initializer_list<value_type> init, size_type bucket_count, 954 const allocator_type& alloc) 955 : unordered_multimap{init, bucket_count, hasher{}, key_equal{}, alloc} 956 { /* DUMMY BODY */ } 957 958 unordered_multimap(initializer_list<value_type> init, size_type bucket_count, 959 const hasher& hf, const allocator_type& alloc) 960 : unordered_multimap{init, bucket_count, hf, key_equal{}, alloc} 961 { /* DUMMY BODY */ } 962 963 ~unordered_multimap() 964 { /* DUMMY BODY */ } 965 966 unordered_multimap& operator=(const unordered_multimap& other) 967 { 968 table_ = other.table_; 969 allocator_ = other.allocator_; 970 971 return *this; 972 } 973 974 unordered_multimap& operator=(unordered_multimap&& other) 975 noexcept(allocator_traits<allocator_type>::is_always_equal::value && 976 is_nothrow_move_assignable<hasher>::value && 977 is_nothrow_move_assignable<key_equal>::value) 978 { 979 table_ = move(other.table_); 980 allocator_ = move(other.allocator_); 981 982 return *this; 983 } 984 985 unordered_multimap& operator=(initializer_list<value_type>& init) 986 { 987 table_.clear(); 988 table_.reserve(init.size()); 989 990 insert(init.begin(), init.end()); 991 992 return *this; 993 } 994 995 allocator_type get_allocator() const noexcept 996 { 997 return allocator_; 998 } 999 1000 bool empty() const noexcept 1001 { 1002 return table_.empty(); 1003 } 1004 1005 size_type size() const noexcept 1006 { 1007 return table_.size(); 1008 } 1009 1010 size_type max_size() const noexcept 1011 { 1012 return table_.max_size(allocator_); 1013 } 1014 1015 iterator begin() noexcept 1016 { 1017 return table_.begin(); 1018 } 1019 1020 const_iterator begin() const noexcept 1021 { 1022 return table_.begin(); 1023 } 1024 1025 iterator end() noexcept 1026 { 1027 return table_.end(); 1028 } 1029 1030 const_iterator end() const noexcept 1031 { 1032 return table_.end(); 1033 } 1034 1035 const_iterator cbegin() const noexcept 1036 { 1037 return table_.cbegin(); 1038 } 1039 1040 const_iterator cend() const noexcept 1041 { 1042 return table_.cend(); 1043 } 1044 1045 template<class... Args> 1046 pair<iterator, bool> emplace(Args&&... args) 1047 { 1048 table_.increment_size(); 1049 1050 auto val = value_type{forward<Args>(args)...}; 1051 auto key = table_.get_key(val); 1052 auto spot = table_.find_insertion_spot(key); 1053 auto bucket = get<0>(spot); 1054 auto idx = get<2>(spot); 1055 1056 if (!bucket) 1057 return make_pair(end(), false); 1058 1059 auto target = table_.find_node_or_return_head(key, *bucket); 1060 auto node = new node_type{move(val)}; 1061 if (target && table_.keys_equal(key, target->value)) 1062 target->append(node); 1063 else 1064 bucket->prepend(node); 1065 1066 return make_pair(iterator{ 1067 table_.table(), idx, 1068 table_.bucket_count(), 1069 node 1070 }, true); 1071 } 1072 1073 template<class... Args> 1074 iterator emplace_hint(const_iterator, Args&&... args) 1075 { 1076 return emplace(forward<Args>(args)...).first; 1077 } 1078 1079 pair<iterator, bool> insert(const value_type& val) 1080 { 1081 table_.increment_size(); 1082 1083 auto key = table_.get_key(val); 1084 auto spot = table_.find_insertion_spot(key); 1085 auto bucket = get<0>(spot); 1086 auto idx = get<2>(spot); 1087 1088 if (!bucket) 1089 return make_pair(end(), false); 1090 1091 auto target = table_.find_node_or_return_head(key, *bucket); 1092 auto node = new node_type{val}; 1093 if (target && table_.keys_equal(key, target->value)) 1094 target->append(node); 1095 else 1096 bucket->prepend(node); 1097 1098 return make_pair(iterator{ 1099 table_.table(), idx, 1100 table_.bucket_count(), 1101 node 1102 }, true); 1103 } 1104 1105 pair<iterator, bool> insert(value_type&& val) 1106 { 1107 table_.increment_size(); 1108 1109 auto key = table_.get_key(val); 1110 auto spot = table_.find_insertion_spot(key); 1111 auto bucket = get<0>(spot); 1112 auto idx = get<2>(spot); 1113 1114 if (!bucket) 1115 return make_pair(end(), false); 1116 1117 auto target = table_.find_node_or_return_head(key, *bucket); 1118 auto node = new node_type{forward<value_type>(val)}; 1119 if (target && table_.keys_equal(key, target->value)) 1120 target->append(node); 1121 else 1122 bucket->prepend(node); 1123 1124 return make_pair(iterator{ 1125 table_.table(), idx, 1126 table_.bucket_count(), 1127 node 1128 }, true); 1129 } 1130 1131 template< 1132 class T, 1133 class = enable_if_t<is_constructible_v<value_type, T&&>, void> 1134 > 1135 pair<iterator, bool> insert(T&& val) 1136 { 1137 return emplace(forward<T>(val)); 1138 } 1139 1140 iterator insert(const_iterator, const value_type& val) 1141 { 1142 return insert(val).first; 1143 } 1144 1145 iterator insert(const_iterator, value_type&& val) 1146 { 1147 return insert(forward<value_type>(val)).first; 1148 } 1149 1150 template< 1151 class T, 1152 class = enable_if_t<is_constructible_v<value_type, T&&>, void> 1153 > 1154 iterator insert(const_iterator hint, T&& val) 1155 { 1156 return emplace_hint(hint, forward<T>(val)); 1157 } 1158 1159 template<class InputIterator> 1160 void insert(InputIterator first, InputIterator last) 1161 { 1162 while (first != last) 1163 insert(*first++); 1164 } 1165 1166 void insert(initializer_list<value_type> init) 1167 { 1168 insert(init.begin(), init.end()); 1169 } 1170 1171 iterator erase(const_iterator position) 1172 { 1173 return table_.erase(position); 1174 } 1175 1176 size_type erase(const key_type& key) 1177 { 1178 return table_.erase(key); 1179 } 1180 1181 iterator erase(const_iterator first, const_iterator last) 1182 { 1183 while (first != last) 1184 first = erase(first); 1185 1186 return iterator{ 1187 table_.table(), first.idx(), 1188 table_.bucket_count(), table_.head(first.idx()) 1189 }; 1190 } 1191 1192 void clear() noexcept 1193 { 1194 table_.clear(); 1195 } 1196 1197 void swap(unordered_multimap& other) 1198 noexcept(allocator_traits<allocator_type>::is_always_equal::value && 1199 noexcept(std::swap(declval<hasher>(), declval<hasher>())) && 1200 noexcept(std::swap(declval<key_equal>(), declval<key_equal>()))) 1201 { 1202 table_.swap(other.table_); 1203 std::swap(allocator_, other.allocator_); 1204 } 1205 1206 hasher hash_function() const 1207 { 1208 return table_.hash_function(); 1209 } 1210 1211 key_equal key_eq() const 1212 { 1213 return table_.key_eq(); 1214 } 1215 1216 iterator find(const key_type& key) 1217 { 1218 return table_.find(key); 1219 } 1220 1221 const_iterator find(const key_type& key) const 1222 { 1223 return table_.find(key); 1224 } 1225 1226 size_type count(const key_type& key) const 1227 { 1228 return table_.count(key); 1229 } 1230 1231 pair<iterator, iterator> equal_range(const key_type& key) 1232 { 1233 return table_.equal_range(key); 1234 } 1235 1236 pair<const_iterator, const_iterator> equal_range(const key_type& key) const 1237 { 1238 return table_.equal_range(key); 1239 } 1240 1241 size_type bucket_count() const noexcept 1242 { 1243 return table_.bucket_count(); 1244 } 1245 1246 size_type max_bucket_count() const noexcept 1247 { 1248 return table_.max_bucket_count(); 1249 } 1250 1251 size_type bucket_size(size_type idx) const 1252 { 1253 return table_.bucket_size(idx); 1254 } 1255 1256 size_type bucket(const key_type& key) const 1257 { 1258 return table_.bucket(key); 1259 } 1260 1261 local_iterator begin(size_type idx) 1262 { 1263 return table_.begin(idx); 1264 } 1265 1266 const_local_iterator begin(size_type idx) const 1267 { 1268 return table_.begin(idx); 1269 } 1270 1271 local_iterator end(size_type idx) 1272 { 1273 return table_.end(idx); 1274 } 1275 1276 const_local_iterator end(size_type idx) const 1277 { 1278 return table_.end(idx); 1279 } 1280 1281 const_local_iterator cbegin(size_type idx) const 1282 { 1283 return table_.cbegin(idx); 1284 } 1285 1286 const_local_iterator cend(size_type idx) const 1287 { 1288 return table_.cend(idx); 1289 } 1290 1291 float load_factor() const noexcept 1292 { 1293 return table_.load_factor(); 1294 } 1295 1296 float max_load_factor() const noexcept 1297 { 1298 return table_.max_load_factor(); 1299 } 1300 1301 void max_load_factor(float factor) 1302 { 1303 table_.max_load_factor(factor); 1304 } 1305 1306 void rehash(size_type bucket_count) 1307 { 1308 table_.rehash(bucket_count); 1309 } 1310 1311 void reserve(size_type count) 1312 { 1313 table_.reserve(count); 1314 } 1315 1316 private: 1317 using table_type = aux::hash_table< 1318 value_type, key_type, aux::key_value_key_extractor<key_type, mapped_type>, 1319 hasher, key_equal, allocator_type, size_type, 1320 iterator, const_iterator, local_iterator, const_local_iterator, 1321 aux::hash_single_policy 1322 >; 1323 using node_type = typename table_type::node_type; 1324 1325 table_type table_; 1326 allocator_type allocator_; 1327 1328 static constexpr size_type default_bucket_count_{16}; 1329 1330 template<class K, class V, class H, class P, class A> 1331 friend bool operator==(unordered_multimap<K, V, H, P, A>&, 1332 unordered_multimap<K, V, H, P, A>&); 1333 }; 853 1334 854 1335 template<class Key, class Value, class Hash, class Pred, class Alloc>
Note:
See TracChangeset
for help on using the changeset viewer.