11#ifndef INCGUARD_MGL_ARRAY_H_1744450834 
   12#define INCGUARD_MGL_ARRAY_H_1744450834 
   20#include <mgl/memory/mgl_memory_utility.h> 
   31template <
class ValueType, 
class IndexType = 
size_t>
 
   36    static_assert(std::is_default_constructible_v<ValueType>, 
"Array element must be constructible by default.");
 
   39    static_assert(std::is_integral_v<IndexType>, 
"IndexType must be integral value.");
 
   52    explicit Array(
size_t arraySize = 0, Memory::ClearMode clearMode = Memory::ClearMode::Auto) 
noexcept 
   54        Allocate(arraySize, clearMode);
 
 
   65    Array(
size_t arraySize, 
const ValueType &invalidValue, Memory::ClearMode clearMode = Memory::ClearMode::Auto) 
noexcept 
   67        Allocate(arraySize, clearMode);
 
 
   79    Array(
size_t arraySize, ValueType &&invalidValue, Memory::ClearMode clearMode = Memory::ClearMode::Auto) 
noexcept 
   81        Allocate(arraySize, clearMode);
 
 
   93        *
this = std::move(rhs);
 
 
  107        _arraySize = rhs._arraySize;
 
 
  138    bool New(
size_t arraySize, Memory::ClearMode clearMode = Memory::ClearMode::Auto) 
noexcept 
  141        if (_tail != 
nullptr)
 
  143            auto invalidValue = std::move(*_tail);    
 
  144            if (Allocate(arraySize, clearMode))
 
  155            return Allocate(arraySize, clearMode);
 
 
  167    bool Renew(Memory::ClearMode clearMode = Memory::ClearMode::Auto) 
noexcept 
  169        return New(_arraySize, clearMode);
 
 
  178    constexpr void Fill(
const ValueType &value) 
noexcept 
  180        for (
auto *e = 
begin(); e != 
end(); e++)
 
 
  193    [[nodiscard]] 
constexpr const ValueType &
Get(IndexType index) 
const noexcept 
  195        return _top[GetIndex(index)];
 
 
  205    [[nodiscard]] 
constexpr const ValueType &
operator[](IndexType index) 
const noexcept 
 
  217    [[nodiscard]] 
constexpr ValueType *
GetPtr(IndexType index) 
noexcept 
  219        if (
auto i = GetIndex(index); i < _arraySize)
 
  221            return std::addressof(_top[i]);
 
 
  234    template <
class LoopBody>
 
  235    constexpr void ForEach(LoopBody body) 
noexcept 
  237        for (
size_t i = 0; i < _arraySize; i++)
 
  239            if (!InvokeLoopBody(body, 
static_cast<IndexType
>(i)))
 
 
  253    template <
class LoopBody>
 
  254    constexpr void ForEach(LoopBody body) 
const noexcept 
  256        for (
size_t i = 0; i < _arraySize; i++)
 
  258            if (!InvokeLoopBody(body, 
static_cast<IndexType
>(i)))
 
 
  274    template <
class LoopBody>
 
  283            std::clamp(
begin, 
static_cast<IndexType
>(0), 
static_cast<IndexType
>(_arraySize) - 1),
 
  284            std::clamp(
end, 
static_cast<IndexType
>(0), 
static_cast<IndexType
>(_arraySize) - 1));
 
  288            if (!InvokeLoopBody(body, i))
 
 
  304    template <
class LoopBody>
 
  313            std::clamp(
begin, 0, 
static_cast<IndexType
>(_arraySize) - 1),
 
  314            std::clamp(
end, 0, 
static_cast<IndexType
>(_arraySize) - 1));
 
  318            if (!InvokeLoopBody(body, i))
 
 
  333    [[nodiscard]] 
constexpr bool Contains(
const ValueType &element) 
const noexcept 
  335        return Contains(std::addressof(element));
 
 
  346    [[nodiscard]] 
constexpr bool Contains(
const ValueType *element) 
const noexcept 
  352        auto topAddress = 
reinterpret_cast<uintptr_t
>(_top);
 
  353        auto elemAddress = 
reinterpret_cast<uintptr_t
>(element);
 
  354        auto tailAddress = 
reinterpret_cast<uintptr_t
>(_tail);
 
  356        return (topAddress <= elemAddress) && (elemAddress < tailAddress);
 
 
  367        if (_tail != 
nullptr)
 
 
  381        if (_tail != 
nullptr)
 
  383            *_tail = std::move(value);
 
 
  393    [[nodiscard]] 
constexpr size_t GetSize() const noexcept
 
 
  404    [[nodiscard]] 
constexpr ValueType *
begin() const noexcept
 
 
  415    [[nodiscard]] 
constexpr ValueType *
end() const noexcept
 
 
  426    [[nodiscard]] 
constexpr const ValueType *
cbegin() const noexcept
 
 
  437    [[nodiscard]] 
constexpr const ValueType *
cend() const noexcept
 
 
  452    bool Allocate(
size_t arraySize, Memory::ClearMode clearMode) 
noexcept 
  455        if ((_top != 
nullptr) && (_arraySize == arraySize))
 
  458            std::destroy_n(_top, _arraySize + 1);
 
  461            _top = Memory::Utility::InitializeArrayBuffer<ValueType>(_top, _arraySize + 1, clearMode);
 
  470            const auto size = 
sizeof(ValueType) * (arraySize + 1);
 
  471            auto *ptr = Memory::Allocate(size);
 
  479            _top = Memory::Utility::InitializeArrayBuffer<ValueType>(ptr, arraySize + 1, clearMode);
 
  482            _tail = std::addressof(_top[arraySize]);
 
  483            _arraySize = arraySize;
 
  494    void Deallocate() noexcept
 
  498            std::destroy_n(_top, _arraySize + 1);
 
  499            Memory::Deallocate(_top);
 
  500            _top = _tail = 
nullptr;
 
  512    [[nodiscard]] 
constexpr size_t GetIndex(IndexType index) 
const noexcept 
  515        if constexpr (std::is_signed_v<IndexType>)
 
  517            if ((index >= 0) && (
static_cast<size_t>(index) < _arraySize))
 
  519                return static_cast<size_t>(index);
 
  525            if (
static_cast<size_t>(index) < _arraySize)
 
  527                return static_cast<size_t>(index);
 
  545    template <
class LoopBody>
 
  546    constexpr bool InvokeLoopBody(LoopBody body, IndexType index) 
noexcept 
  549        if constexpr (std::is_invocable_r_v<bool, 
decltype(body), IndexType, 
ValueType &>)
 
  551            return body(index, _top[GetIndex(index)]);
 
  554        else if constexpr (std::is_invocable_r_v<void, 
decltype(body), IndexType, 
ValueType &>)
 
  556            body(index, _top[GetIndex(index)]);
 
  560        else if constexpr (std::is_invocable_r_v<bool, 
decltype(body), 
ValueType &>)
 
  562            return body(_top[GetIndex(index)]);
 
  565        else if constexpr (std::is_invocable_r_v<void, 
decltype(body), 
ValueType &>)
 
  567            body(_top[GetIndex(index)]);
 
  573            static_assert(std::false_type::value, 
"Loop body is not matching arguments.");
 
  588    template <
class LoopBody>
 
  589    constexpr bool InvokeLoopBody(LoopBody body, IndexType index) 
const noexcept 
  592        if constexpr (std::is_invocable_r_v<bool, 
decltype(body), IndexType, 
ValueType &>)
 
  594            return body(index, _top[GetIndex(index)]);
 
  597        else if constexpr (std::is_invocable_r_v<void, 
decltype(body), IndexType, 
ValueType &>)
 
  599            body(index, _top[GetIndex(index)]);
 
  603        else if constexpr (std::is_invocable_r_v<bool, 
decltype(body), 
ValueType &>)
 
  605            return body(_top[GetIndex(index)]);
 
  608        else if constexpr (std::is_invocable_r_v<void, 
decltype(body), 
ValueType &>)
 
  610            body(_top[GetIndex(index)]);
 
  616            static_assert(std::false_type::value, 
"Loop body is not matching arguments.");
 
  621    size_t _arraySize{0};
 
 
動的配列クラス
Definition mgl_array.h:33
 
constexpr void ForEach(LoopBody body) noexcept
全ての要素へのアクセス
Definition mgl_array.h:235
 
constexpr void SetInvalidValue(const ValueType &value) noexcept
無効値の設定
Definition mgl_array.h:365
 
constexpr bool Contains(const ValueType *element) const noexcept
指定した要素が範囲内に含まれているかを取得
Definition mgl_array.h:346
 
constexpr const ValueType & Get(IndexType index) const noexcept
要素の取得
Definition mgl_array.h:193
 
constexpr ValueType * GetPtr(IndexType index) noexcept
書き込み可能な要素へのポインタを取得
Definition mgl_array.h:217
 
Array(size_t arraySize=0, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array.h:52
 
Array(size_t arraySize, const ValueType &invalidValue, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array.h:65
 
constexpr bool Contains(const ValueType &element) const noexcept
指定した要素が範囲内に含まれているかを取得
Definition mgl_array.h:333
 
constexpr void SetInvalidValue(ValueType &&value) noexcept
無効値の設定
Definition mgl_array.h:379
 
constexpr void ForRange(IndexType begin, IndexType end, LoopBody body) const noexcept
範囲を指定して読み取り専用で要素にアクセス
Definition mgl_array.h:305
 
~Array() noexcept
デストラクタ
Definition mgl_array.h:124
 
bool Renew(Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
配列を同じサイズで構築し直す
Definition mgl_array.h:167
 
constexpr ValueType * begin() const noexcept
先頭の要素を取得
Definition mgl_array.h:404
 
constexpr const ValueType & operator[](IndexType index) const noexcept
添字による要素の取得
Definition mgl_array.h:205
 
constexpr void ForEach(LoopBody body) const noexcept
全ての要素へ読み取り専用でアクセス
Definition mgl_array.h:254
 
Array & operator=(Array &&rhs) noexcept
ムーブ代入
Definition mgl_array.h:102
 
constexpr ValueType * end() const noexcept
末尾の要素を取得
Definition mgl_array.h:415
 
Array(size_t arraySize, ValueType &&invalidValue, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
コンストラクタ
Definition mgl_array.h:79
 
bool New(size_t arraySize, Memory::ClearMode clearMode=Memory::ClearMode::Auto) noexcept
配列の生成
Definition mgl_array.h:138
 
constexpr const ValueType * cend() const noexcept
末尾の要素をconstで取得
Definition mgl_array.h:437
 
constexpr void ForRange(IndexType begin, IndexType end, LoopBody body) noexcept
範囲を指定して要素にアクセス
Definition mgl_array.h:275
 
constexpr size_t GetSize() const noexcept
配列の要素数を取得
Definition mgl_array.h:393
 
constexpr void Fill(const ValueType &value) noexcept
全ての要素を指定値で書き込む
Definition mgl_array.h:178
 
constexpr const ValueType * cbegin() const noexcept
先頭の要素をconstで取得
Definition mgl_array.h:426
 
Array(Array &&rhs) noexcept
ムーブコンストラクタ
Definition mgl_array.h:91
 
値の範囲を表現するクラス
Definition mgl_range.h:28
 
constexpr bool Contains(T value) const noexcept
指定された値が範囲内に含まれているかを取得
Definition mgl_range.h:154
 
constexpr T Next(T value) const noexcept
指定された値の次の値を取得
Definition mgl_range.h:115
 
constexpr T Begin() const noexcept
開始値を取得
Definition mgl_range.h:49
 
ValueType
値のタイプ
Definition mgl_achievement_defs.h:33
 
#define MGL_ASSERT(...)
アサート用マクロ
Definition mgl_system_debug_macro.h:88