Commit e5faa86e authored by Kenton Varda's avatar Kenton Varda

Replace KJ_ARRAY_SIZE macro with a template function.

parent 7f083a62
......@@ -749,7 +749,7 @@ void doTest() {
auto file = parsedFile.initRoot();
file.setFile();
file.initId().initUid().setValue(0x8123456789abcdefllu);
auto decls = file.initNestedDecls(3 + KJ_ARRAY_SIZE(TYPE_OPTIONS));
auto decls = file.initNestedDecls(3 + kj::size(TYPE_OPTIONS));
{
auto decl = decls[0];
......@@ -775,7 +775,7 @@ void doTest() {
auto enumerants = decl.initNestedDecls(4);
for (uint i = 0; i < KJ_ARRAY_SIZE(RFC3092); i++) {
for (uint i = 0; i < kj::size(RFC3092); i++) {
auto enumerantDecl = enumerants[i];
enumerantDecl.initName().setValue(RFC3092[i]);
enumerantDecl.getId().initOrdinal().setValue(i);
......@@ -784,7 +784,7 @@ void doTest() {
}
// For each of TYPE_OPTIONS, declare a struct type that contains that type as its @0 field.
for (uint i = 0; i < KJ_ARRAY_SIZE(TYPE_OPTIONS); i++) {
for (uint i = 0; i < kj::size(TYPE_OPTIONS); i++) {
auto decl = decls[3 + i];
auto& option = TYPE_OPTIONS[i];
......
......@@ -75,7 +75,7 @@ public:
// remove it from the holes, and return its offset (as a multiple of its size). If there
// is no such space, returns zero (no hole can be at offset zero, as explained above).
if (lgSize >= KJ_ARRAY_SIZE(holes)) {
if (lgSize >= kj::size(holes)) {
return nullptr;
} else if (holes[lgSize] != 0) {
UIntType result = holes[lgSize];
......@@ -100,12 +100,12 @@ public:
}
void addHolesAtEnd(UIntType lgSize, UIntType offset,
UIntType limitLgSize = KJ_ARRAY_SIZE(holes)) {
UIntType limitLgSize = sizeof(holes) / sizeof(holes[0])) {
// Add new holes of progressively larger sizes in the range [lgSize, limitLgSize) starting
// from the given offset. The idea is that you just allocated an lgSize-sized field from
// an limitLgSize-sized space, such as a newly-added word on the end of the data segment.
KJ_DREQUIRE(limitLgSize <= KJ_ARRAY_SIZE(holes));
KJ_DREQUIRE(limitLgSize <= kj::size(holes));
while (lgSize < limitLgSize) {
KJ_DREQUIRE(holes[lgSize] == 0);
......@@ -144,7 +144,7 @@ public:
kj::Maybe<uint> smallestAtLeast(uint size) {
// Return the size of the smallest hole that is equal to or larger than the given size.
for (uint i = size; i < KJ_ARRAY_SIZE(holes); i++) {
for (uint i = size; i < kj::size(holes); i++) {
if (holes[i] != 0) {
return i;
}
......@@ -158,7 +158,7 @@ public:
// If there is a 32-bit hole with a 32-bit offset, no more than the first 32 bits are used.
// If no more than the first 32 bits are used, and there is a 16-bit hole with a 16-bit
// offset, then no more than the first 16 bits are used. And so on.
for (uint i = KJ_ARRAY_SIZE(holes); i > 0; i--) {
for (uint i = kj::size(holes); i > 0; i--) {
if (holes[i - 1] != 1) {
return i;
}
......
......@@ -57,7 +57,7 @@ uint64_t generateChildId(uint64_t parentId, kj::StringPtr childName) {
}
Md5 md5;
md5.update(kj::arrayPtr(parentIdBytes, KJ_ARRAY_SIZE(parentIdBytes)));
md5.update(kj::arrayPtr(parentIdBytes, kj::size(parentIdBytes)));
md5.update(childName);
kj::ArrayPtr<const kj::byte> resultBytes = md5.finish();
......
......@@ -27,6 +27,16 @@
namespace kj {
namespace {
TEST(Common, Size) {
int arr[] = {12, 34, 56, 78};
size_t expected = 0;
for (size_t i: indices(arr)) {
EXPECT_EQ(expected++, i);
}
EXPECT_EQ(4, expected);
}
TEST(Common, Maybe) {
{
Maybe<int> m = 123;
......
......@@ -198,8 +198,6 @@ void unreachable() KJ_NORETURN;
kj::arrayPtr(name##_stack, name##_size) : name##_heap
#endif
#define KJ_ARRAY_SIZE(arr) (sizeof(arr) / sizeof(arr[0]))
#define KJ_CONCAT_(x, y) x##y
#define KJ_CONCAT(x, y) KJ_CONCAT_(x, y)
#define KJ_UNIQUE_NAME(prefix) KJ_CONCAT(prefix, __LINE__)
......@@ -337,6 +335,13 @@ inline constexpr auto min(T&& a, U&& b) -> decltype(a < b ? a : b) { return a <
template <typename T, typename U>
inline constexpr auto max(T&& a, U&& b) -> decltype(a > b ? a : b) { return a > b ? a : b; }
template <typename T, size_t s>
inline constexpr size_t size(T (&arr)[s]) { return s; }
template <typename T>
inline constexpr size_t size(T&& arr) { return arr.size(); }
// Returns the size of the parameter, whether the parameter is a regular C array or a container
// with a `.size()` method.
// =======================================================================================
// Useful fake containers
......@@ -384,13 +389,22 @@ private:
};
template <typename T>
inline constexpr Range<Decay<T>> range(T&& begin, T&& end) { return Range<Decay<T>>(begin, end); }
inline constexpr Range<Decay<T>> range(T begin, T end) { return Range<Decay<T>>(begin, end); }
// Returns a fake iterable container containing all values of T from `begin` (inclusive) to `end`
// (exclusive). Example:
//
// // Prints 1, 2, 3, 4, 5, 6, 7, 8, 9.
// for (int i: kj::range(1, 10)) { print(i); }
template <typename T>
inline constexpr Range<size_t> indices(T&& container) {
// Shortcut for iterating over the indices of a container:
//
// for (size_t i: kj::indices(myArray)) { handle(myArray[i]); }
return range<size_t>(0, kj::size(container));
}
template <typename T>
class Repeat {
public:
......
......@@ -82,7 +82,7 @@ String getStackSymbols(ArrayPtr<void* const> trace) {
char line[512];
size_t i = 0;
while (i < KJ_ARRAY_SIZE(lines) && fgets(line, sizeof(line), p) != nullptr) {
while (i < kj::size(lines) && fgets(line, sizeof(line), p) != nullptr) {
// Don't include exception-handling infrastructure in stack trace.
if (i == 0 &&
(strstr(line, "kj/common.c++") != nullptr ||
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment