Skip to content

Commit fe55715

Browse files
committed
Added compat header
1 parent c80020f commit fe55715

File tree

5 files changed

+54
-19
lines changed

5 files changed

+54
-19
lines changed

src/chunk.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "./chunk.h"
2+
#include <compat.hpp>
23
#include <functional>
34

45
namespace mcmap {

src/helper.h

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -70,23 +70,4 @@ fs::path getHome();
7070
fs::path getSaveDir();
7171
fs::path getTempDir();
7272

73-
// TODO Finesse this atrocity out of existence
74-
template <typename F>
75-
typename std::map<int, F>::const_iterator
76-
compatible(const std::map<int, F> &hash, int version) {
77-
auto it = hash.rbegin();
78-
int compatible = 0;
79-
80-
while (it != hash.rend()) {
81-
if (it->first <= version) {
82-
compatible = it->first;
83-
break;
84-
}
85-
86-
it++;
87-
}
88-
89-
return hash.find(compatible);
90-
}
91-
9273
#endif // HELPER_H_

src/include/compat.hpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
#include <map>
3+
4+
/* Loosely inspired from lower_bound in
5+
* /usr/include/c++/11.1.0/bits/stl_algobase.h
6+
* Returns a const_iterator to the highest integer that is inferior or equal to
7+
* `version` from the keys of a map<int, F> */
8+
template <typename F>
9+
typename std::map<int, F>::const_iterator
10+
compatible(const std::map<int, F> &hash, int version) {
11+
typedef typename std::map<int, F>::const_iterator _Iterator;
12+
typedef typename _Iterator::difference_type _DistanceType;
13+
14+
_Iterator __first = hash.begin(), __end = hash.end();
15+
_DistanceType __len = std::distance(__first, __end);
16+
17+
while (__len > 1) {
18+
_DistanceType __half = __len >> 1;
19+
_Iterator __middle = __first;
20+
std::advance(__middle, __half);
21+
22+
if (__middle->first > version)
23+
__end = __middle;
24+
else
25+
__first = __middle;
26+
27+
__len = __len - __half;
28+
}
29+
30+
return __first;
31+
}

src/section.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "./section.h"
2+
#include <compat.hpp>
23
#include <functional>
34

45
namespace versions {

tests/test_compat.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <cmath>
2+
#include <compat.hpp>
3+
#include <gtest/gtest.h>
4+
5+
TEST(TestCompat, TestReturn) {
6+
std::map<int, int> versions = {
7+
{0, 0}, {1, 0}, {2, 0}, {4, 0}, {8, 0}, {16, 0},
8+
};
9+
10+
std::map<int, int>::const_iterator it;
11+
12+
it = compatible(versions, 0);
13+
ASSERT_NE(it, versions.end());
14+
ASSERT_EQ(it->first, 0);
15+
16+
for (int i = 1; i < 20; i++) {
17+
it = compatible(versions, i);
18+
ASSERT_NE(it, versions.end());
19+
ASSERT_EQ(it->first, 1 << int(std::log2(double(i))));
20+
}
21+
}

0 commit comments

Comments
 (0)