Skip to content

The yasio::pod_vector aka array_buffer concept #368

@halx99

Description

@halx99

The pod_vector more efficient than std::vector when element type is pod or trivially_copyable, especially load small file whole content to buffer one-time with follow design:

The pod_vector aka array_buffer concepts:

  • Use realloc for memory alloc & free, benefit use OS API directly, such as win32 API HeapRealloc
  • The memory model is similar to to std::vector, but only accept trivially_copyable(no destructor & no custom copy constructor) types
  • The resize behavior differrent stl, always allocate exactly
  • By default resize without fill (uninitialized and for overwrite)
  • Support release internal buffer ownership with release_pointer
  • Transparent iterator
  • no data/precision lost (TODO: change to same with std::vector maybe better)
  • expand/append/insert/push_back will trigger memory allocate growth strategy MSVC
  • Implemented c+23 API: resize_and_overwrite

Alias

  • array_buffer
  • byte_buffer: array_buffer<uint8_t>
  • sbyte_buffer: array_buffer<char>

The implement

https://github.com/yasio/yasio/blob/experimental/yasio/pod_vector.hpp

issue, std::vector also exist initializer_list constructor

std::vector<uint32_t> xxx{(size_t)128, (uint32_t)0}; // xxx will have 2 elements with {128, 0} insetad 128 elements with value 0
yasio::pod_vector<uint32_t> xxx{(size_t)128, (uint32_t)0}; 

emplace_back for POD type without constructor

struct ATest {
  int a;
  int b;
  int c;
};

struct BTest {
  BTest(int xx, int yy, int zz) : x(xx), y(yy), z(zz) {}
  int x;
  int y; 
  int z;
};

std::vector<ATest> vec0;
vec0.emplace_back(1, 2, 3); // not working on std < c++20

yasio::pod_vector<ATest> vec1;
vec1.emplace_back(1, 2, 3); // working on all std >= c++11

std::vector<BTest> vec00;
vec00.emplace_back(1, 2, 3); // works

yasio::pod_vector<BTest> vec11;
vec11.emplace_back(1, 2, 3); // works

placement new align

inline _LIBCPP_INLINE_VISIBILITY void *__libcpp_allocate(size_t __size, size_t __align) {
#ifndef _LIBCPP_HAS_NO_ALIGNED_ALLOCATION
  if (__is_overaligned_for_new(__align)) {
    const align_val_t __align_val = static_cast<align_val_t>(__align);
# ifdef _LIBCPP_HAS_NO_BUILTIN_OVERLOADED_OPERATOR_NEW_DELETE
    return ::operator new(__size, __align_val);
# else
    return __builtin_operator_new(__size, __align_val);
# endif
  }
#else
  ((void)__align);
#endif
#ifdef _LIBCPP_HAS_NO_BUILTIN_OPERATOR_NEW_DELETE
  return ::operator new(__size);
#else
  return __builtin_operator_new(__size);
#endif
}
_LIBCPP_CONSTEXPR inline _LIBCPP_INLINE_VISIBILITY bool __is_overaligned_for_new(size_t __align) _NOEXCEPT {
#ifdef __STDCPP_DEFAULT_NEW_ALIGNMENT__
  return __align > __STDCPP_DEFAULT_NEW_ALIGNMENT__;
#else
  return __align > alignment_of<max_align_t>::value;
#endif
}
image

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions