array now accounts for alignment

v1
Brett 2024-03-07 11:38:09 -05:00
parent 56b569e0fd
commit 3f06d0e619
2 changed files with 42 additions and 18 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.5) cmake_minimum_required(VERSION 3.5)
include(cmake/color.cmake) include(cmake/color.cmake)
set(BLT_VERSION 0.13.5) set(BLT_VERSION 0.13.6)
set(BLT_TEST_VERSION 0.0.1) set(BLT_TEST_VERSION 0.0.1)
set(BLT_TARGET BLT) set(BLT_TARGET BLT)

View File

@ -24,10 +24,12 @@
#include <blt/std/memory_util.h> #include <blt/std/memory_util.h>
#include <stdexcept> #include <stdexcept>
#include <iterator> #include <iterator>
#include <memory>
#include "logging.h"
namespace blt namespace blt
{ {
//#define ALIGN_TO(x, size) (((x) + size - 1) & ~(size - 1))
template<typename T = void> template<typename T = void>
class array class array
{ {
@ -37,56 +39,76 @@ namespace blt
using reverse_iterator = std::reverse_iterator<iterator>; using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>;
private: private:
struct metadata struct metadata_t
{ {
// size in number of elements! // size in number of elements!
blt::size_t size; blt::size_t size;
explicit metadata(blt::size_t size): size(size) explicit metadata_t(blt::size_t size): size(size)
{} {}
} metadata; } metadata;
T* _data = static_cast<T*>(static_cast<blt::u8*>(this) + sizeof(metadata)); static constexpr blt::size_t ALIGNMENT = std::max(sizeof(metadata_t), alignof(T));
public:
inline T* _data()
{
return reinterpret_cast<T*>(reinterpret_cast<blt::u8*>(this) + ALIGNMENT);
}
/** /**
* constructs an array out of a block of memory of size bytes * constructs an array out of a block of memory of size bytes
* @param size number of bytes available in the memory allocated to this array. * @param size number of bytes available in the memory allocated to this array.
*/ */
explicit array(blt::size_t size): metadata( (size - sizeof(metadata)) / sizeof(T)) explicit array(blt::size_t size): metadata((size - sizeof(metadata)) / sizeof(T))
{} {}
public:
inline static array* construct(void* ptr, blt::size_t size)
{
auto aligned_ptr = std::align(alignof(array), sizeof(array), ptr, size);
return new (aligned_ptr) array<T> {size};
}
array(const array&) = delete;
array(array&&) = delete;
array& operator=(const array&) = delete;
array& operator=(array&&) = delete;
inline T& operator[](blt::size_t index) inline T& operator[](blt::size_t index)
{ {
return _data[index]; return _data()[index];
} }
inline const T& operator[](blt::size_t index) const inline const T& operator[](blt::size_t index) const
{ {
return _data[index]; return _data()[index];
} }
[[nodiscard]] inline T& at(blt::size_t index) [[nodiscard]] inline T& at(blt::size_t index)
{ {
if (index > size()) if (index > size())
throw std::runtime_error("Index " + std::to_string(index) += " is outside the bounds of this array!"); throw std::runtime_error("Index " + std::to_string(index) += " is outside the bounds of this array!");
return _data[index]; return _data()[index];
} }
[[nodiscard]] inline const T& at(blt::size_t index) const [[nodiscard]] inline const T& at(blt::size_t index) const
{ {
if (index > size()) if (index > size())
throw std::runtime_error("Index " + std::to_string(index) += " is outside the bounds of this array!"); throw std::runtime_error("Index " + std::to_string(index) += " is outside the bounds of this array!");
return _data[index]; return _data()[index];
} }
[[nodiscard]] inline T* data() [[nodiscard]] inline T* data()
{ {
return _data; return _data();
} }
[[nodiscard]] inline T* data() const [[nodiscard]] inline T* data() const
{ {
return _data; return _data();
} }
[[nodiscard]] inline blt::size_t size() const [[nodiscard]] inline blt::size_t size() const
@ -101,27 +123,27 @@ namespace blt
constexpr inline T* operator*() constexpr inline T* operator*()
{ {
return _data; return data();
} }
constexpr inline T& front() constexpr inline T& front()
{ {
return *_data; return *_data();
} }
constexpr inline const T& front() const constexpr inline const T& front() const
{ {
return *_data; return *data();
} }
constexpr inline T& back() constexpr inline T& back()
{ {
return _data[size() - 1]; return data()[size() - 1];
} }
constexpr inline const T& back() const constexpr inline const T& back() const
{ {
return _data[size() - 1]; return data()[size() - 1];
} }
constexpr inline iterator begin() const noexcept constexpr inline iterator begin() const noexcept
@ -163,6 +185,8 @@ namespace blt
{ {
return reverse_iterator{cbegin()}; return reverse_iterator{cbegin()};
} }
~array() = default;
}; };
} }