diff --git a/.gitignore b/.gitignore index a77f72f2a..9628118d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ +basis/src build -include/meevax/basis include/meevax/unicode src/kernel/version.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 6008cbafa..dcd7e9160 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -64,6 +64,33 @@ string(TOLOWER ${CMAKE_SYSTEM_NAME} ${PROJECT_NAME}_SYSTEM_NAME) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure/README.md ${CMAKE_CURRENT_SOURCE_DIR}/README.md) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure/version.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/kernel/version.cpp) +# ---- Target basis ------------------------------------------------------------ + +file(GLOB ${PROJECT_NAME}_BASIS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/basis/*.ss) + +foreach(EACH IN LISTS ${PROJECT_NAME}_BASIS_SOURCES) + get_filename_component(FILENAME ${EACH} NAME) + file(READ ${EACH} ${FILENAME}) +endforeach() + +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/configure/basis.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/basis/src/basis.cpp) + +add_library(basis SHARED) + +target_sources(basis PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/basis/src/basis.cpp) + +target_include_directories(basis + PUBLIC $ + PUBLIC $) + +set_target_properties(basis PROPERTIES + OUTPUT_NAME ${PROJECT_NAME}-basis # Rename libbasis => libmeevax-basis + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} + LINK_FLAGS_RELEASE -s) + # ---- Target kernel ----------------------------------------------------------- add_library(kernel SHARED) @@ -81,25 +108,18 @@ target_link_libraries(kernel PUBLIC gmp) set_target_properties(kernel PROPERTIES - OUTPUT_NAME ${PROJECT_NAME} # Rename libkernel => libmeevax + OUTPUT_NAME ${PROJECT_NAME}-kernel # Rename libkernel => libmeevax-kernel VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR} LINK_FLAGS_RELEASE -s) -# ---- Target basis ------------------------------------------------------------ - -add_custom_target(basis - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/configure/basis.cmake) - # ---- Target shell ------------------------------------------------------------ add_executable(shell) -add_dependencies(shell basis) - target_sources(shell PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp) -target_link_libraries(shell PRIVATE kernel) +target_link_libraries(shell PRIVATE basis kernel) set_target_properties(shell PROPERTIES OUTPUT_NAME ${PROJECT_NAME} # Rename shell => meevax @@ -116,7 +136,7 @@ write_basic_package_version_file( # ---- Target install ---------------------------------------------------------- install( # /usr/lib/libmeevax - TARGETS kernel + TARGETS basis kernel EXPORT ${PROJECT_NAME}-config ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) @@ -126,7 +146,8 @@ install( # /usr/bin/meevax RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) install( # /usr/include/meevax - DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ + ${CMAKE_CURRENT_SOURCE_DIR}/basis/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install( # /usr/share/meevax/meevax-config.cmake @@ -135,8 +156,7 @@ install( # /usr/share/meevax/meevax-config.cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME} NAMESPACE Meevax::) -# /usr/share/meevax/meevax-config-version.cmake -install( +install( # /usr/share/meevax/meevax-config-version.cmake FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake DESTINATION ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME}) @@ -180,14 +200,14 @@ file(GLOB ${PROJECT_NAME}_TEST_CPP ${CMAKE_CURRENT_SOURCE_DIR}/test/*.cpp) foreach(EACH IN LISTS ${PROJECT_NAME}_TEST_CPP) get_filename_component(FILENAME ${EACH} NAME_WE) - add_executable(assert-${FILENAME} ${EACH}) - add_dependencies(assert-${FILENAME} basis) - target_link_libraries(assert-${FILENAME} PRIVATE kernel) + add_executable(test_${FILENAME} ${EACH}) + target_link_libraries(test_${FILENAME} PRIVATE basis kernel) + target_compile_options(test_${FILENAME} PUBLIC -Wno-deprecated-declarations) add_test( - NAME assert-${FILENAME} + NAME test/${FILENAME} COMMAND ${${PROJECT_NAME}_MEMORY_CHECK_COMMAND} ${${PROJECT_NAME}_MEMORY_CHECK_OPTIONS} - ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/assert-${FILENAME}) + ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/test_${FILENAME}) endforeach() # ---- Additional Targets ------------------------------------------------------ diff --git a/README.md b/README.md index fd5737181..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.107_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.107.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.107_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 1722d5958..e8b2b30cf 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.107 +0.5.119 diff --git a/basis/include/meevax/basis.hpp b/basis/include/meevax/basis.hpp new file mode 100644 index 000000000..9fe642b3a --- /dev/null +++ b/basis/include/meevax/basis.hpp @@ -0,0 +1,27 @@ +/* + Copyright 2018-2023 Tatsuya Yamasaki. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef INCLUDED_MEEVAX_KERNEL_BASIS_HPP +#define INCLUDED_MEEVAX_KERNEL_BASIS_HPP + +#include + +namespace meevax +{ + auto basis() -> std::vector; +} // namespace meevax + +#endif // INCLUDED_MEEVAX_KERNEL_BASIS_HPP 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/configure/basis.cmake b/configure/basis.cmake deleted file mode 100644 index 32884bc9c..000000000 --- a/configure/basis.cmake +++ /dev/null @@ -1,15 +0,0 @@ -execute_process( - COMMAND git rev-parse --show-toplevel - COMMAND tr -d "\n" - OUTPUT_VARIABLE TOPLEVEL) - -file(GLOB ${PROJECT_NAME}_BASIS_SOURCES ${TOPLEVEL}/basis/*.ss) - -foreach(EACH IN LISTS ${PROJECT_NAME}_BASIS_SOURCES) - get_filename_component(FILENAME ${EACH} NAME) - file(READ ${EACH} ${FILENAME}) -endforeach() - -configure_file( - ${TOPLEVEL}/configure/basis.hpp - ${TOPLEVEL}/include/meevax/basis/scheme.hpp) diff --git a/configure/basis.hpp b/configure/basis.cpp similarity index 72% rename from configure/basis.hpp rename to configure/basis.cpp index eac3bb9ee..cc6bc4a33 100644 --- a/configure/basis.hpp +++ b/configure/basis.cpp @@ -14,24 +14,13 @@ limitations under the License. */ -#ifndef INCLUDED_MEEVAX_KERNEL_BASIS_HPP -#define INCLUDED_MEEVAX_KERNEL_BASIS_HPP - -#include +#include namespace meevax { -inline namespace kernel -{ - template - constexpr auto make_array(Ts&&... xs) -> std::array>, sizeof...(Ts)> - { - return { std::forward(xs)... }; - } - - constexpr auto basis() + auto basis() -> std::vector { - return make_array( + return { R"##(${meevax.ss})##", R"##(${r4rs.ss})##", R"##(${r5rs.ss})##", @@ -53,9 +42,7 @@ inline namespace kernel R"##(${srfi-78.ss})##", R"##(${srfi-98.ss})##", R"##(${srfi-111.ss})##", - R"##(${srfi-149.ss})##"); + R"##(${srfi-149.ss})##", + }; } -} // namespace kernel } // namespace meevax - -#endif // INCLUDED_MEEVAX_KERNEL_BASIS_HPP diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 89ab24b6b..ddfccd93a 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -10,7 +10,7 @@ add_library(${PROJECT_NAME} SHARED ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.c target_compile_options(${PROJECT_NAME} PUBLIC "-Wno-return-type-c-linkage") -target_link_libraries(${PROJECT_NAME} PRIVATE Meevax::kernel) +target_link_libraries(${PROJECT_NAME} PRIVATE Meevax::kernel Meevax::basis) enable_testing() diff --git a/example/example.cpp b/example/example.cpp index ce76447fd..7d3e75608 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -1,3 +1,4 @@ +#include #include using namespace meevax; // NOTE: DIRTY HACK diff --git a/include/meevax/kernel/pair.hpp b/include/meevax/kernel/pair.hpp index 2ea70c124..a5b02366f 100644 --- a/include/meevax/kernel/pair.hpp +++ b/include/meevax/kernel/pair.hpp @@ -136,7 +136,11 @@ inline namespace kernel using const_iterator = forward_iterator; - explicit pair(object const& = unit, object const& = unit); + constexpr pair() = default; + + explicit pair(object const&); + + explicit pair(object const&, object const&); template > explicit pair(object const& a, Ts&&... xs) diff --git a/include/meevax/kernel/procedure.hpp b/include/meevax/kernel/procedure.hpp index 186592ee8..338f06808 100644 --- a/include/meevax/kernel/procedure.hpp +++ b/include/meevax/kernel/procedure.hpp @@ -45,9 +45,10 @@ inline namespace kernel { std::enable_if_t or std::is_invocable_v, F> invocable; - explicit generic_procedure(std::string const& name, F f) - : primitive_procedure { name } - , invocable { f } + template + explicit generic_procedure(T && x, U && y) + : primitive_procedure { std::forward(x) } + , invocable { std::forward(y) } {} auto operator ()(object & xs) const -> object override diff --git a/include/meevax/memory/collector.hpp b/include/meevax/memory/collector.hpp index 02ce15d9b..0c9675431 100644 --- a/include/meevax/memory/collector.hpp +++ b/include/meevax/memory/collector.hpp @@ -121,14 +121,14 @@ inline namespace memory friend class collector; protected: - tag * location = nullptr; + tag * object = nullptr; explicit constexpr mutator() = default; - explicit mutator(tag * location) noexcept - : location { location } + explicit mutator(tag * object) noexcept + : object { object } { - if (location) + if (object) { mutators.insert(this); } @@ -136,7 +136,7 @@ inline namespace memory ~mutator() noexcept { - if (location) + if (object) { mutators.erase(this); } @@ -144,7 +144,7 @@ inline namespace memory auto reset(tag * after = nullptr) noexcept -> void { - if (auto before = std::exchange(location, after); not before and after) + if (auto before = std::exchange(object, after); not before and after) { mutators.insert(this); } @@ -181,9 +181,9 @@ inline namespace memory protected: static inline tag * cache = nullptr; - static inline pointer_set tags {}; + static inline v2::pointer_set tags {}; - static inline pointer_set mutators {}; + static inline v2::pointer_set mutators {}; static inline std::size_t allocation = 0; diff --git a/include/meevax/memory/gc_pointer.hpp b/include/meevax/memory/gc_pointer.hpp index 3161b8b14..c737a9398 100644 --- a/include/meevax/memory/gc_pointer.hpp +++ b/include/meevax/memory/gc_pointer.hpp @@ -33,7 +33,7 @@ inline namespace memory gc_pointer(gc_pointer const& gcp) : pointer { gcp } - , collector::mutator { gcp.location } + , collector::mutator { gcp.object } {} gc_pointer(pointer const& p) @@ -72,7 +72,7 @@ inline namespace memory auto reset(gc_pointer const& gcp) -> void { pointer::reset(gcp); - collector::mutator::reset(gcp.location); + collector::mutator::reset(gcp.object); } auto reset(pointer const& p) -> void diff --git a/include/meevax/memory/heterogeneous_pointer.hpp b/include/meevax/memory/heterogeneous_pointer.hpp index 4f6d1bc87..6a7443487 100644 --- a/include/meevax/memory/heterogeneous_pointer.hpp +++ b/include/meevax/memory/heterogeneous_pointer.hpp @@ -43,7 +43,9 @@ inline namespace memory { template explicit constexpr binder(Us&&... xs) - : std::conditional_t, Top, Bound> { std::forward(xs)... } + : std::conditional_t and std::is_constructible_v, Top, Bound> { + std::forward(xs)... + } {} ~binder() override = default; diff --git a/include/meevax/memory/integer_set.hpp b/include/meevax/memory/integer_set.hpp new file mode 100644 index 000000000..1394c74f5 --- /dev/null +++ b/include/meevax/memory/integer_set.hpp @@ -0,0 +1,380 @@ +/* + Copyright 2018-2023 Tatsuya Yamasaki. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef INCLUDED_MEEVAX_MEMORY_INTEGER_SET_HPP +#define INCLUDED_MEEVAX_MEMORY_INTEGER_SET_HPP + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace meevax +{ +inline namespace memory +{ + template + constexpr auto compressible_bitwidth_of = std::is_pointer_v ? log2(alignof(std::remove_pointer_t)) - 1 : 0; + + template + struct integer_set + { + static_assert(sizeof(T) <= sizeof(std::uintptr_t)); + + static_assert(compressible_bitwidth_of < E); + + static constexpr auto N = static_cast(1) << (E - compressible_bitwidth_of); + + using subset = integer_set; // Only the outermost implementation knows the original type name T. + + subset * data[N] = {}; + + struct const_iterator : public std::iterator + { + subset const* const* data = nullptr; + + std::size_t i = std::numeric_limits::max(); + + typename subset::const_iterator iter; + + constexpr const_iterator() = default; + + explicit const_iterator(integer_set const* container, std::size_t i, std::uintptr_t j = 0) noexcept + : data { container->data } + , i { i } + { + assert(i <= N); + increment_unless_truthy(j); + } + + explicit const_iterator(integer_set const* container) noexcept + : data { container->data } + , i { N } + { + decrement_unless_truthy(); + assert(iter.data); + } + + auto increment_unless_truthy(std::uintptr_t j = 0) noexcept -> void + { + assert(data); + + for (; good(); ++i, j = 0) + { + if (data[i] and (iter = data[i]->lower_bound(j)).good()) + { + return; + } + } + + iter = {}; + } + + auto decrement_unless_truthy() noexcept -> void + { + assert(data); + + for (i = std::min(i, N - 1); good(); --i) + { + if (data[i] and (iter = typename subset::const_iterator(data[i])).good()) + { + return; + } + } + + iter = {}; + } + + auto operator ++() noexcept -> auto & + { + if (++iter; not iter.good()) + { + ++i; + increment_unless_truthy(); + } + + return *this; + } + + auto operator --() noexcept -> auto & + { + if (not iter.data) + { + decrement_unless_truthy(); + } + else if (--iter; not iter.good()) + { + --i; + decrement_unless_truthy(); + } + + return *this; + } + + auto operator *() const noexcept -> T + { + assert(good()); + return reinterpret_cast((i << (Es + ...) bitor *iter) << compressible_bitwidth_of); + } + + auto good() const noexcept -> bool + { + assert(data); + return i < N; + } + + auto at_end() const noexcept -> bool + { + return not data or not good() or iter.at_end(); + } + + auto is_same_index(const_iterator const& other) const noexcept -> bool + { + return i == other.i and iter.is_same_index(other.iter); + } + + friend auto operator ==(const_iterator const& a, const_iterator const& b) noexcept + { + return a.is_same_index(b) or (a.at_end() and b.at_end()); + } + + friend auto operator !=(const_iterator const& a, const_iterator const& b) noexcept + { + return not (a == b); + } + }; + + static constexpr auto split(T p) noexcept + { + static_assert(E + (Es + ...) <= sizeof(T) * CHAR_BIT); + + struct big_endian + { + std::uintptr_t ignore : sizeof(std::uintptr_t) * CHAR_BIT - E - (Es + ...); + std::uintptr_t key : E - compressible_bitwidth_of; + std::uintptr_t value : (Es + ...); + std::uintptr_t : compressible_bitwidth_of; + }; + + struct little_endian + { + std::uintptr_t : compressible_bitwidth_of; + std::uintptr_t value : (Es + ...); + std::uintptr_t key : E - compressible_bitwidth_of; + std::uintptr_t ignore : sizeof(std::uintptr_t) * CHAR_BIT - E - (Es + ...); + }; + + const auto bits = bit_cast(p); + + return std::make_pair(bits.key, bits.value); + } + + ~integer_set() + { + for (auto datum : data) + { + delete datum; + } + } + + auto insert(T value) + { + if (auto [key, datum] = split(value); data[key]) + { + data[key]->insert(datum); + } + else + { + data[key] = new subset(); + data[key]->insert(datum); + } + } + + auto erase(T value) noexcept + { + auto [i, j] = split(value); + data[i]->erase(j); + } + + auto begin() const noexcept + { + return const_iterator(this, 0); + } + + auto end() const noexcept + { + return const_iterator(this, N); + } + + auto lower_bound(T value) const noexcept + { + auto [i, j] = split(value); + return const_iterator(this, i, j); + } + + auto size() const noexcept -> std::size_t + { + return std::distance(begin(), end()); + } + }; + + template + struct integer_set + { + static_assert(std::is_same_v); + + static constexpr auto N = 1ul << E; + + std::uint64_t data[N / 64] {}; + + struct const_iterator : public std::iterator + { + std::uint64_t const* data = nullptr; + + std::size_t index = std::numeric_limits::max(); + + auto increment_unless_truthy() noexcept + { + 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; + } + } + + index = N; + + assert(not good()); + } + + auto decrement_unless_truthy() noexcept + { + 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; + } + } + + index = N; + + assert(not good()); + } + + constexpr const_iterator() = default; + + explicit const_iterator(integer_set const* container, std::size_t i) noexcept + : data { container->data } + , index { i } + { + increment_unless_truthy(); + } + + explicit const_iterator(integer_set const* container) noexcept + : data { container->data } + , index { N - 1 } + { + decrement_unless_truthy(); + } + + auto operator ++() noexcept -> decltype(auto) + { + ++index; + increment_unless_truthy(); + return *this; + } + + auto operator --() noexcept -> decltype(auto) + { + --index; + decrement_unless_truthy(); + return *this; + } + + auto operator *() const noexcept + { + assert(good()); + return reinterpret_cast(index); + } + + auto good() const noexcept -> bool + { + assert(data); + return index < N; + } + + auto at_end() const noexcept -> bool + { + return not data or not good(); + } + + auto is_same_index(const_iterator const& other) const noexcept -> bool + { + return index == other.index; + } + + friend auto operator ==(const_iterator const& a, const_iterator const& b) noexcept + { + return a.is_same_index(b) or (a.at_end() and b.at_end()); + } + + friend auto operator !=(const_iterator const& a, const_iterator const& b) noexcept + { + return not (a == b); + } + }; + + auto insert(T value) noexcept + { + auto i = reinterpret_cast(value) / 64; + auto j = reinterpret_cast(value) % 64; + data[i] |= (1ul << j); + } + + auto erase(T value) noexcept + { + auto i = reinterpret_cast(value) / 64; + auto j = reinterpret_cast(value) % 64; + data[i] &= ~(1ul << j); + } + + auto lower_bound(T value) const noexcept + { + return const_iterator(this, reinterpret_cast(value)); + } + }; +} // namespace memory +} // namespace meevax + +#endif // INCLUDED_MEEVAX_MEMORY_INTEGER_SET_HPP diff --git a/include/meevax/memory/pointer_set.hpp b/include/meevax/memory/pointer_set.hpp index 45f87af0c..b0fd052de 100644 --- a/include/meevax/memory/pointer_set.hpp +++ b/include/meevax/memory/pointer_set.hpp @@ -31,16 +31,19 @@ #include #include #include +#include namespace meevax { inline namespace memory +{ +inline namespace v1 { template typename Map = simple_flat_map, + template typename OrderedMap = simple_flat_map, template typename Bitset = simple_bitset, std::size_t N = 4096 * 8> // getconf PAGE_SIZE - class pointer_set + class [[deprecated]] pointer_set { static_assert(std::is_pointer_v); @@ -92,9 +95,7 @@ inline namespace memory } }; - Map chunks; - - std::unordered_map::iterator> cache; + OrderedMap chunks; public: struct iterator @@ -109,14 +110,14 @@ inline namespace memory using difference_type = std::ptrdiff_t; - Map const& chunks; + OrderedMap const& chunks; - typename Map::const_iterator outer; + typename OrderedMap::const_iterator outer; typename chunk::const_iterator inner; - explicit iterator(Map const& chunks, - typename Map::const_iterator outer, + explicit iterator(OrderedMap const& chunks, + typename OrderedMap::const_iterator outer, std::size_t hint) : chunks { chunks } , outer { outer } @@ -129,7 +130,7 @@ inline namespace memory } } - explicit iterator(Map const& chunks) + explicit iterator(OrderedMap const& chunks) : chunks { chunks } , outer { chunks.end() } , inner {} @@ -240,23 +241,6 @@ inline namespace memory assert(begin() == end()); } - auto chunks_lower_bound(std::size_t offset) - { - if (auto iter = cache.find(offset); iter != cache.end()) - { - return iter->second; - } - else if (auto iter = chunks.lower_bound(offset); iter != chunks.end()) - { - cache.emplace(iter->first, iter); - return iter; - } - else - { - return iter; - } - } - auto size() const -> std::size_t { return std::distance(begin(), end()); @@ -264,7 +248,7 @@ inline namespace memory auto insert(compact_pointer p) { - if (auto iter = chunks_lower_bound(p.offset()); iter != chunks.end() and iter->first == p.offset()) + if (auto iter = chunks.lower_bound(p.offset()); iter != chunks.end() and iter->first == p.offset()) { iter->second.set(p.index()); } @@ -272,13 +256,12 @@ inline namespace memory { assert(iter == chunks.end() or p.offset() < iter->first); chunks.emplace_hint(iter, p.offset(), p.index()); - cache.clear(); } } auto erase(compact_pointer p) { - auto iter = chunks_lower_bound(p.offset()); + auto iter = chunks.lower_bound(p.offset()); assert(iter != chunks.end()); iter->second.reset(p.index()); } @@ -295,7 +278,7 @@ inline namespace memory auto lower_bound(compact_pointer p) { - if (auto iter = chunks_lower_bound(p.offset()); iter != chunks.end()) + if (auto iter = chunks.lower_bound(p.offset()); iter != chunks.end()) { return iterator(chunks, iter, p.index()); } @@ -305,6 +288,14 @@ inline namespace memory } } }; +} // namespace v1 + +namespace v2 +{ + template + struct pointer_set : integer_set + {}; +} // namespace v2 } // namespace memory } // namespace meevax diff --git a/src/kernel/exact_integer.cpp b/src/kernel/exact_integer.cpp index 826af9c93..85ab62834 100644 --- a/src/kernel/exact_integer.cpp +++ b/src/kernel/exact_integer.cpp @@ -103,7 +103,7 @@ inline namespace kernel if (mpz_init_set_str(value, (s.at(0) == '+' ? s.substr(1) : s).c_str(), radix)) { mpz_clear(value); - throw std::invalid_argument("not a integer"); + throw std::invalid_argument("not an exact-integer"); } } diff --git a/src/kernel/number.cpp b/src/kernel/number.cpp index 9e01b36d0..c723d3e93 100644 --- a/src/kernel/number.cpp +++ b/src/kernel/number.cpp @@ -424,7 +424,7 @@ inline namespace kernel } catch (std::invalid_argument const&) { - return make(ratio(literal, radix)); + return make(literal, radix); } } @@ -487,7 +487,7 @@ inline namespace kernel } catch (std::invalid_argument const&) { - return make(complex(literal, radix)); + return make(literal, radix); } } diff --git a/src/kernel/pair.cpp b/src/kernel/pair.cpp index bd4604808..3d8ca0305 100644 --- a/src/kernel/pair.cpp +++ b/src/kernel/pair.cpp @@ -22,6 +22,10 @@ inline namespace kernel { let unit { nullptr }; + pair::pair(object const& a) + : std::pair { a, unit } + {} + pair::pair(object const& a, object const& b) : std::pair { a, b } {} diff --git a/src/main.cpp b/src/main.cpp index 33a6a6424..2dfdc45b7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,7 +14,7 @@ limitations under the License. */ -#include +#include #include #include #include diff --git a/src/memory/collector.cpp b/src/memory/collector.cpp index ac3de4ded..9c5413ba0 100644 --- a/src/memory/collector.cpp +++ b/src/memory/collector.cpp @@ -123,11 +123,11 @@ inline namespace memory for (auto&& mutator : mutators) { assert(mutator); - assert(mutator->location); + assert(mutator->object); - if (not mutator->location->marked() and is_root_object(mutator)) + if (not mutator->object->marked() and is_root_object(mutator)) { - mark(mutator->location); + mark(mutator->object); } } } @@ -145,7 +145,7 @@ inline namespace memory for (auto iter = mutators.lower_bound(lower_address); iter != mutators.end() and *iter < upper_address; ++iter) { - mark((*iter)->location); + mark((*iter)->object); } } } diff --git a/test/environment.cpp b/test/environment.cpp index 9665f6cdd..a0b2b51ff 100644 --- a/test/environment.cpp +++ b/test/environment.cpp @@ -1,7 +1,7 @@ #undef NDEBUG #include -#include +#include #include #include #include diff --git a/test/pointer_set.cpp b/test/pointer_set.cpp index 273312e22..2e58330fb 100644 --- a/test/pointer_set.cpp +++ b/test/pointer_set.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include #include @@ -112,10 +113,12 @@ auto measure() auto main() -> int { - std::cout << measure>() << std::endl; - std::cout << measure>() << std::endl; - std::cout << measure>() << std::endl; - std::cout << measure>() << std::endl; + std::cout << measure>() << std::endl; + std::cout << measure>() << std::endl; + std::cout << measure>() << std::endl; + std::cout << measure>() << std::endl; + + std::cout << measure>() << std::endl; return EXIT_SUCCESS; }