@@ -27,6 +27,7 @@ Author: Daniel Poetzl
27
27
#include < type_traits>
28
28
#include < vector>
29
29
30
+ #include " as_const.h"
30
31
#include " irep.h"
31
32
#include " optional.h"
32
33
#include " sharing_node.h"
@@ -518,7 +519,7 @@ class sharing_mapt
518
519
protected:
519
520
// helpers
520
521
521
- leaft * get_leaf_node (const key_type &k);
522
+ leaft & get_leaf_node (const key_type &k);
522
523
const leaft *get_leaf_node (const key_type &k) const ;
523
524
524
525
// / Move a leaf node further down the tree such as to resolve a collision with
@@ -1062,7 +1063,7 @@ ::get_delta_view(
1062
1063
while (!stack.empty ());
1063
1064
}
1064
1065
1065
- SHARING_MAPT2 (, leaft * )::get_leaf_node(const key_type &k)
1066
+ SHARING_MAPT2 (, leaft & )::get_leaf_node(const key_type &k)
1066
1067
{
1067
1068
SM_ASSERT (has_key (k));
1068
1069
@@ -1074,9 +1075,8 @@ SHARING_MAPT2(, leaft *)::get_leaf_node(const key_type &k)
1074
1075
{
1075
1076
std::size_t bit = key & mask;
1076
1077
1077
- ip = ip->add_child (bit);
1078
- SM_ASSERT (ip != nullptr );
1079
- SM_ASSERT (!ip->empty ()); // since the key must exist in the map
1078
+ ip = &ip->add_child (bit);
1079
+ PRECONDITION (!ip->empty ()); // since the key must exist in the map
1080
1080
1081
1081
if (ip->is_internal ())
1082
1082
{
@@ -1085,17 +1085,14 @@ SHARING_MAPT2(, leaft *)::get_leaf_node(const key_type &k)
1085
1085
}
1086
1086
else if (ip->is_leaf ())
1087
1087
{
1088
- return ip;
1088
+ return * ip;
1089
1089
}
1090
1090
else
1091
1091
{
1092
1092
SM_ASSERT (ip->is_defined_container ());
1093
- return ip->find_leaf (k);
1093
+ return * ip->find_leaf (k);
1094
1094
}
1095
1095
}
1096
-
1097
- UNREACHABLE;
1098
- return nullptr ;
1099
1096
}
1100
1097
1101
1098
SHARING_MAPT2 (const , leaft *)::get_leaf_node(const key_type &k) const
@@ -1152,15 +1149,15 @@ SHARING_MAPT(void)::erase(const key_type &k)
1152
1149
{
1153
1150
std::size_t bit = key & mask;
1154
1151
1155
- const to_mapt &m = as_const (ip)->get_to_map ();
1152
+ const to_mapt &m = as_const_ptr (ip)->get_to_map ();
1156
1153
1157
1154
if (m.size () > 1 || del == nullptr )
1158
1155
{
1159
1156
del = ip;
1160
1157
del_bit=bit;
1161
1158
}
1162
1159
1163
- ip = ip->add_child (bit);
1160
+ ip = & ip->add_child (bit);
1164
1161
1165
1162
PRECONDITION (!ip->empty ());
1166
1163
@@ -1181,7 +1178,8 @@ SHARING_MAPT(void)::erase(const key_type &k)
1181
1178
else
1182
1179
{
1183
1180
SM_ASSERT (ip->is_defined_container ());
1184
- const leaf_listt &ll = as_const (ip)->get_container ();
1181
+ const leaf_listt &ll = as_const_ptr (ip)->get_container ();
1182
+ PRECONDITION (!ll.empty ());
1185
1183
1186
1184
// forward list has one element
1187
1185
if (std::next (ll.begin ()) == ll.end ())
@@ -1215,7 +1213,7 @@ ::migrate(
1215
1213
SM_ASSERT (starting_level < levels - 1 );
1216
1214
SM_ASSERT (inner.is_defined_internal ());
1217
1215
1218
- leaft &leaf = * inner.add_child (bit_last);
1216
+ leaft &leaf = inner.add_child (bit_last);
1219
1217
SM_ASSERT (leaf.is_defined_leaf ());
1220
1218
1221
1219
std::size_t key_existing = hash ()(leaf.get_key ());
@@ -1248,19 +1246,19 @@ ::migrate(
1248
1246
{
1249
1247
// Place found
1250
1248
1251
- innert * l1 = ip->add_child (bit_existing);
1252
- SM_ASSERT (l1-> empty ());
1253
- l1-> swap (leaf_kept);
1249
+ innert & l1 = ip->add_child (bit_existing);
1250
+ SM_ASSERT (l1. empty ());
1251
+ l1. swap (leaf_kept);
1254
1252
1255
- innert * l2 = ip->add_child (bit);
1256
- SM_ASSERT (l2-> empty ());
1257
- l2-> make_leaf (k, std::forward<valueU>(m));
1253
+ innert & l2 = ip->add_child (bit);
1254
+ SM_ASSERT (l2. empty ());
1255
+ l2. make_leaf (k, std::forward<valueU>(m));
1258
1256
1259
1257
return ;
1260
1258
}
1261
1259
1262
1260
SM_ASSERT (bit == bit_existing);
1263
- ip = ip->add_child (bit);
1261
+ ip = & ip->add_child (bit);
1264
1262
1265
1263
key >>= chunk;
1266
1264
key_existing >>= chunk;
@@ -1302,39 +1300,39 @@ ::insert(const key_type &k, valueU &&m)
1302
1300
SM_ASSERT (ip->is_internal ());
1303
1301
SM_ASSERT (level == 0 || !ip->empty ());
1304
1302
1305
- innert * child = ip->add_child (bit);
1303
+ innert & child = ip->add_child (bit);
1306
1304
1307
1305
// Place is unoccupied
1308
- if (child-> empty ())
1306
+ if (child. empty ())
1309
1307
{
1310
1308
if (level < levels - 1 )
1311
1309
{
1312
1310
// Create leaf
1313
- child-> make_leaf (k, m);
1311
+ child. make_leaf (k, m);
1314
1312
}
1315
1313
else
1316
1314
{
1317
1315
SM_ASSERT (level == levels - 1 );
1318
1316
1319
1317
// Create container and insert leaf
1320
- child-> place_leaf (k, std::forward<valueU>(m));
1318
+ child. place_leaf (k, std::forward<valueU>(m));
1321
1319
1322
- SM_ASSERT (child-> is_defined_container ());
1320
+ SM_ASSERT (child. is_defined_container ());
1323
1321
}
1324
1322
1325
1323
num++;
1326
1324
1327
1325
return ;
1328
1326
}
1329
- else if (child-> is_internal ())
1327
+ else if (child. is_internal ())
1330
1328
{
1331
- ip = child;
1329
+ ip = & child;
1332
1330
key >>= chunk;
1333
1331
level++;
1334
1332
1335
1333
continue ;
1336
1334
}
1337
- else if (child-> is_leaf ())
1335
+ else if (child. is_leaf ())
1338
1336
{
1339
1337
// migrate leaf downwards
1340
1338
migrate (level, key, bit, *ip, k, std::forward<valueU>(m));
@@ -1345,11 +1343,11 @@ ::insert(const key_type &k, valueU &&m)
1345
1343
}
1346
1344
else
1347
1345
{
1348
- SM_ASSERT (child-> is_defined_container ());
1346
+ SM_ASSERT (child. is_defined_container ());
1349
1347
SM_ASSERT (level == levels - 1 );
1350
1348
1351
1349
// Add to the container
1352
- child-> place_leaf (k, std::forward<valueU>(m));
1350
+ child. place_leaf (k, std::forward<valueU>(m));
1353
1351
1354
1352
num++;
1355
1353
@@ -1361,28 +1359,26 @@ ::insert(const key_type &k, valueU &&m)
1361
1359
SHARING_MAPT4 (valueU, void )
1362
1360
::replace(const key_type &k, valueU &&m)
1363
1361
{
1364
- leaft *lp = get_leaf_node (k);
1365
- PRECONDITION (lp != nullptr ); // key must exist in map
1362
+ leaft &lp = get_leaf_node (k);
1366
1363
1367
1364
INVARIANT (
1368
- !value_equalt ()(as_const (lp)-> get_value (), m),
1365
+ !value_equalt ()(as_const (lp). get_value (), m),
1369
1366
" values should not be replaced with equal values to maximize sharing" );
1370
1367
1371
- lp-> set_value (std::forward<valueU>(m));
1368
+ lp. set_value (std::forward<valueU>(m));
1372
1369
}
1373
1370
1374
1371
SHARING_MAPT (void )
1375
1372
::update(const key_type &k, std::function<void (mapped_type &)> mutator)
1376
1373
{
1377
- leaft *lp = get_leaf_node (k);
1378
- PRECONDITION (lp != nullptr ); // key must exist in map
1374
+ leaft &lp = get_leaf_node (k);
1379
1375
1380
- value_comparatort comparator (as_const (lp)-> get_value ());
1376
+ value_comparatort comparator (as_const (lp). get_value ());
1381
1377
1382
- lp-> mutate_value (mutator);
1378
+ lp. mutate_value (mutator);
1383
1379
1384
1380
INVARIANT (
1385
- !comparator (as_const (lp)-> get_value ()),
1381
+ !comparator (as_const (lp). get_value ()),
1386
1382
" sharing_mapt::update should make some change. Consider using read-only "
1387
1383
" method to check if an update is needed beforehand" );
1388
1384
}
0 commit comments