Skip to content

Commit

Permalink
Update (increment|decrement)_unless_truthy to be faster
Browse files Browse the repository at this point in the history
Signed-off-by: yamacir-kit <[email protected]>
  • Loading branch information
yamacir-kit committed Feb 18, 2024
1 parent 80cca00 commit e6dbc64
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 28 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Latest release is [here](https://github.com/yamacir-kit/meevax/releases).
- Low-level hygienic macro system, known as *syntactic closures* [[Bawden and
Rees 1988](#Bawden-and-Rees-1988); [Hanson 1991](#Hanson-1991)] and *explicit
renaming* [[Clinger 1991](#Clinger-1991)]. For these, the well-known macro
transformers `sc-macro-transformer`, `rsc-macro-transformer`, and
transformers `sc-macro-transformer`, `rsc-macro-transformer` and
`er-macro-transformer` from the library [`(meevax
macro-transformer)`](./basis/meevax.ss) are provided. Note that these are
non-Scheme standards.
Expand Down Expand Up @@ -91,7 +91,7 @@ Procedures for each standard are provided by the following R7RS-style libraries:
cmake -B build -DCMAKE_BUILD_TYPE=Release
cd build
make package
sudo apt install build/meevax_0.5.118_amd64.deb
sudo apt install build/meevax_0.5.119_amd64.deb
```

or
Expand Down Expand Up @@ -123,9 +123,9 @@ sudo rm -rf /usr/local/share/meevax

| Target Name | Description
|-------------|-------------
| `all` | Build shared-library `libmeevax.0.5.118.so` and executable `meevax`
| `all` | Build shared-library `libmeevax.0.5.119.so` and executable `meevax`
| `test` | Test executable `meevax`
| `package` | Generate debian package `meevax_0.5.118_amd64.deb`
| `package` | Generate debian package `meevax_0.5.119_amd64.deb`
| `install` | Copy files into `/usr/local` directly

## Usage
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.5.118
0.5.119
2 changes: 1 addition & 1 deletion configure/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ Latest release is [here](https://github.com/yamacir-kit/meevax/releases).
- Low-level hygienic macro system, known as *syntactic closures* [[Bawden and
Rees 1988](#Bawden-and-Rees-1988); [Hanson 1991](#Hanson-1991)] and *explicit
renaming* [[Clinger 1991](#Clinger-1991)]. For these, the well-known macro
transformers `sc-macro-transformer`, `rsc-macro-transformer`, and
transformers `sc-macro-transformer`, `rsc-macro-transformer` and
`er-macro-transformer` from the library [`(meevax
macro-transformer)`](./basis/meevax.ss) are provided. Note that these are
non-Scheme standards.
Expand Down
74 changes: 52 additions & 22 deletions include/meevax/memory/integer_set.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#include <array>
#include <cassert>
#include <climits>
#include <cstdint>
#include <iterator>
#include <limits>
#include <type_traits>
Expand Down Expand Up @@ -239,73 +240,98 @@ inline namespace memory
template <typename T, std::size_t E>
struct integer_set<T, E>
{
static constexpr auto N = static_cast<std::size_t>(1) << E;
static_assert(std::is_same_v<decltype(0ul), std::uint64_t>);

bool data[N] {};
static constexpr auto N = 1ul << E;

std::uint64_t data[N / 64] {};

struct const_iterator : public std::iterator<std::bidirectional_iterator_tag, T>
{
bool const* data = nullptr;
std::uint64_t const* data = nullptr;

std::size_t i = std::numeric_limits<std::size_t>::max();
std::size_t index = std::numeric_limits<std::size_t>::max();

auto increment_unless_truthy() noexcept
{
for (assert(data); good() and not data[i]; ++i)
{}
auto i = index / 64;
auto j = index % 64;

for (; i < N / 64; ++i, j = 0)
{
if (auto datum = data[i] & (~0ul << j); datum)
{
index = i * 64 + __builtin_ctzl(datum);
assert(data[index / 64] & (1ul << index % 64));
return;
}
}

assert(not good() or data[i]);
index = N;

assert(not good());
}

auto decrement_unless_truthy() noexcept
{
for (assert(data); good() and not data[i]; --i)
{}
auto i = index / 64;
auto j = index % 64;

for (; i < N / 64; --i, j = 63)
{
if (auto datum = data[i] & (~0ul >> (63 - j)); datum)
{
index = i * 64 + (63 - __builtin_clzl(datum));
assert(data[index / 64] & (1ul << index % 64));
return;
}
}

assert(not good() or data[i]);
index = N;

assert(not good());
}

constexpr const_iterator() = default;

explicit const_iterator(integer_set const* container, std::size_t i) noexcept
: data { container->data }
, i { i }
: data { container->data }
, index { i }
{
increment_unless_truthy();
assert(not good() or data[this->i]);
}

explicit const_iterator(integer_set const* container) noexcept
: data { container->data }
, i { N - 1 }
: data { container->data }
, index { N - 1 }
{
decrement_unless_truthy();
}

auto operator ++() noexcept -> decltype(auto)
{
++i;
++index;
increment_unless_truthy();
return *this;
}

auto operator --() noexcept -> decltype(auto)
{
--i;
--index;
decrement_unless_truthy();
return *this;
}

auto operator *() const noexcept
{
assert(good());
return reinterpret_cast<T>(i);
return reinterpret_cast<T>(index);
}

auto good() const noexcept -> bool
{
assert(data);
return i < N;
return index < N;
}

auto at_end() const noexcept -> bool
Expand All @@ -315,7 +341,7 @@ inline namespace memory

auto is_same_index(const_iterator const& other) const noexcept -> bool
{
return i == other.i;
return index == other.index;
}

friend auto operator ==(const_iterator const& a, const_iterator const& b) noexcept
Expand All @@ -331,12 +357,16 @@ inline namespace memory

auto insert(T value) noexcept
{
data[reinterpret_cast<std::size_t>(value)] = true;
auto i = reinterpret_cast<std::size_t>(value) / 64;
auto j = reinterpret_cast<std::size_t>(value) % 64;
data[i] |= (1ul << j);
}

auto erase(T value) noexcept
{
data[reinterpret_cast<std::size_t>(value)] = false;
auto i = reinterpret_cast<std::size_t>(value) / 64;
auto j = reinterpret_cast<std::size_t>(value) % 64;
data[i] &= ~(1ul << j);
}

auto lower_bound(T value) const noexcept
Expand Down

0 comments on commit e6dbc64

Please sign in to comment.