Skip to content

Commit

Permalink
Merge pull request #170 from eseiler/misc/generalise_resize
Browse files Browse the repository at this point in the history
[MISC] Generalised uninitialised resize
  • Loading branch information
eseiler authored Nov 22, 2023
2 parents dda26fb + 6a03932 commit a6d88e3
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 10 deletions.
38 changes: 33 additions & 5 deletions cmake/configuration.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -161,15 +161,44 @@ endif ()

set (HIBF_UNINITIALISED_RESIZE_TEST_SOURCE
"#include <cstddef>
#include <cstdint>
#include <vector>
struct my_vector : public std::vector<int>
struct my_vector : public std::vector<uint64_t>
{
void resize_for_overwrite(size_t const size)
using base_t = std::vector<uint64_t>;
#ifdef _LIBCPP_VERSION
inline void resize_for_overwrite(size_t const size)
{
struct fake_vector
{
using allocator_t = typename base_t::allocator_type;
using pointer = typename std::allocator_traits<allocator_t>::pointer;
pointer begin;
pointer end;
std::__compressed_pair<pointer, allocator_t> end_cap;
};
static_assert(sizeof(fake_vector) == sizeof(base_t));
static_assert(alignof(fake_vector) == alignof(base_t));
if (size > base_t::capacity())
base_t::reserve(size);
fake_vector & vec = reinterpret_cast<fake_vector &>(*this);
vec.end = vec.begin + size;
}
#else
inline void resize_for_overwrite(size_t const size)
{
this->_M_create_storage(size);
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
if (size > base_t::capacity())
base_t::reserve(size);
this->_M_impl._M_finish = this->_M_impl._M_start + size;
}
#endif
};
int main()
Expand Down Expand Up @@ -222,7 +251,6 @@ else ()
# CMake's check_ipo_supported uses hardcoded lto flags
# macOS GCC supports -flto-auto, but not the hardcoded flag "-fno-fat-lto-objects"
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Darwin")

set (HIBF_LTO_FLAGS "-flto=auto -ffat-lto-objects")
else ()
set (HIBF_LTO_FLAGS "-flto=auto")
Expand Down
51 changes: 46 additions & 5 deletions include/hibf/misc/bit_vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -918,15 +918,56 @@ class bit_vector :
//!\endcond

private:
// If nothing else works: Just use `resize`.
#ifndef HIBF_UNINITIALISED_RESIZE
HIBF_CONSTEXPR_VECTOR inline void resize_for_overwrite(size_t const size)
{
#ifdef HIBF_UNINITIALISED_RESIZE
this->_M_create_storage(size);
this->_M_impl._M_finish = this->_M_impl._M_end_of_storage;
#else
base_t::resize(size);
#endif
}
#else
// libc++: reinterpret_cast to a struct that has the same layout as std::vector.
// All internal members are private.
# if defined(_LIBCPP_VERSION)
inline void resize_for_overwrite(size_t const size)
{
struct fake_vector
{
using allocator_t = typename base_t::allocator_type;
using pointer = typename std::allocator_traits<allocator_t>::pointer;

pointer begin;
pointer end;
std::__compressed_pair<pointer, allocator_t> end_cap;
};

static_assert(sizeof(fake_vector) == sizeof(base_t));
static_assert(alignof(fake_vector) == alignof(base_t));

if (size > base_t::capacity())
base_t::reserve(size);

// Annotate the new memory as contiguous container for llvm's address sanitizer.
# ifndef _LIBCPP_HAS_NO_ASAN
__sanitizer_annotate_contiguous_container(base_t::data(),
base_t::data() + base_t::capacity(),
base_t::data() + base_t::size(),
base_t::data() + size);
# endif

fake_vector & vec = reinterpret_cast<fake_vector &>(*this);
vec.end = vec.begin + size;
}
// libstdc++: The internal members are protected, so we can access them.
# else
HIBF_CONSTEXPR_VECTOR inline void resize_for_overwrite(size_t const size)
{
if (size > base_t::capacity())
base_t::reserve(size);

this->_M_impl._M_finish = this->_M_impl._M_start + size;
}
# endif
#endif

//!\brief Performs the binary bitwise-operation on the underlying chunks.
template <typename binary_operator_t>
Expand Down

1 comment on commit a6d88e3

@vercel
Copy link

@vercel vercel bot commented on a6d88e3 Nov 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

hibf – ./

hibf.vercel.app
hibf-seqan.vercel.app
hibf-git-main-seqan.vercel.app

Please sign in to comment.