diff --git a/README.md b/README.md index f632461dd..6a483660c 100644 --- a/README.md +++ b/README.md @@ -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. @@ -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 @@ -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 diff --git a/VERSION b/VERSION index 8a3133c5c..e8b2b30cf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.118 +0.5.119 diff --git a/configure/README.md b/configure/README.md index fae35493a..41ccda9b2 100644 --- a/configure/README.md +++ b/configure/README.md @@ -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. diff --git a/include/meevax/memory/integer_set.hpp b/include/meevax/memory/integer_set.hpp index c175f4dfc..1394c74f5 100644 --- a/include/meevax/memory/integer_set.hpp +++ b/include/meevax/memory/integer_set.hpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -239,59 +240,84 @@ inline namespace memory template struct integer_set { - static constexpr auto N = static_cast(1) << E; + static_assert(std::is_same_v); - bool data[N] {}; + static constexpr auto N = 1ul << E; + + std::uint64_t data[N / 64] {}; struct const_iterator : public std::iterator { - bool const* data = nullptr; + std::uint64_t const* data = nullptr; - std::size_t i = std::numeric_limits::max(); + std::size_t index = std::numeric_limits::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; } @@ -299,13 +325,13 @@ inline namespace memory auto operator *() const noexcept { assert(good()); - return reinterpret_cast(i); + return reinterpret_cast(index); } auto good() const noexcept -> bool { assert(data); - return i < N; + return index < N; } auto at_end() const noexcept -> bool @@ -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 @@ -331,12 +357,16 @@ inline namespace memory auto insert(T value) noexcept { - data[reinterpret_cast(value)] = true; + auto i = reinterpret_cast(value) / 64; + auto j = reinterpret_cast(value) % 64; + data[i] |= (1ul << j); } auto erase(T value) noexcept { - data[reinterpret_cast(value)] = false; + auto i = reinterpret_cast(value) / 64; + auto j = reinterpret_cast(value) % 64; + data[i] &= ~(1ul << j); } auto lower_bound(T value) const noexcept