array now accounts for alignment
parent
56b569e0fd
commit
3f06d0e619
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue