Skip to content

Commit

Permalink
Merge pull request #5 from KredeGC/dev
Browse files Browse the repository at this point in the history
Dev
  • Loading branch information
KredeGC authored Jun 23, 2023
2 parents 4c5e768 + 8c33eb9 commit c864b03
Show file tree
Hide file tree
Showing 18 changed files with 380 additions and 166 deletions.
51 changes: 51 additions & 0 deletions .github/workflows/dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Test

on:
pull_request:
branches: [ master ]
paths-ignore:
- '**/*.md'
- '**/*.gitignore'
- '**/Doxyfile'

jobs:
Build:
strategy:
matrix:
machine:
- os: ubuntu-latest
action: gmake2
toolset: gcc
- os: ubuntu-latest
action: gmake2
toolset: clang
- os: windows-latest
action: vs2019
toolset: msc
runs-on: ${{ matrix.machine.os }}
permissions:
actions: read
contents: read
security-events: write
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup premake
uses: abel0b/setup-premake@v2.2
with:
version: "5.0.0-beta1"
- name: Install GCC
if: matrix.machine.os == 'ubuntu-latest' && matrix.machine.toolset == 'gcc'
run: sudo apt-get update && sudo apt-get install -y gcc g++
- name: Install Clang & LLVM
if: matrix.machine.os == 'ubuntu-latest' && matrix.machine.toolset == 'clang'
run: sudo apt-get update && sudo apt-get install -y clang llvm lld
- name: Install msbuild to PATH
if: matrix.machine.os == 'windows-latest' && matrix.machine.toolset == 'msc'
uses: microsoft/setup-msbuild@v1.1
- name: Run premake
run: premake5 ${{ matrix.machine.action }} --toolset=${{ matrix.machine.toolset }} --dialect=C++20
- name: Build
run: premake5 build --config=debug
- name: Run test
run: premake5 test --config=debug
12 changes: 3 additions & 9 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
name: Test
name: Staging

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
paths-ignore:
- '**/*.md'
- '**/*.gitignore'
- '**/Doxyfile'

jobs:
Build:
Expand Down Expand Up @@ -49,13 +43,13 @@ jobs:
if: matrix.machine.os == 'windows-latest' && matrix.machine.toolset == 'msc'
uses: microsoft/setup-msbuild@v1.1
- name: Run premake
run: premake5 ${{ matrix.machine.action }} --toolset=${{ matrix.machine.toolset }}
run: premake5 ${{ matrix.machine.action }} --toolset=${{ matrix.machine.toolset }} --dialect=${{ matrix.dialect }}
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
with:
languages: cpp
- name: Build
run: premake5 build --config=${{ matrix.config }} --dialect=${{ matrix.dialect }}
run: premake5 build --config=${{ matrix.config }}
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
- name: Run test
Expand Down
47 changes: 34 additions & 13 deletions include/ktl/allocators/cascading.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ namespace ktl
cascading() noexcept :
m_Node(nullptr) {}

cascading(const cascading&) noexcept = delete;
cascading(const cascading&) = delete;

cascading(cascading&& other) noexcept :
m_Node(other.m_Node)
cascading(cascading&& other)
noexcept(std::is_nothrow_move_constructible_v<node>) :
m_Node(std::move(other.m_Node))
{
other.m_Node = nullptr;
}
Expand All @@ -58,13 +59,14 @@ namespace ktl
release();
}

cascading& operator=(const cascading&) noexcept = delete;
cascading& operator=(const cascading&) = delete;

cascading& operator=(cascading&& rhs) noexcept
cascading& operator=(cascading&& rhs)
noexcept(std::is_nothrow_move_assignable_v<node>)
{
release();

m_Node = rhs.m_Node;
m_Node = std::move(rhs.m_Node);

rhs.m_Node = nullptr;

Expand All @@ -88,13 +90,16 @@ namespace ktl
* @param n The amount of bytes to allocate memory for
* @return A location in memory that is at least @p n bytes big or nullptr if it could not be allocated
*/
void* allocate(size_type n)
void* allocate(size_type n) noexcept(
std::is_nothrow_default_constructible_v<node> &&
detail::has_nothrow_allocate_v<Alloc> &&
(!detail::has_max_size_v<Alloc> || detail::has_nothrow_max_size_v<Alloc>))
{
// Add an initial allocator
if (!m_Node)
m_Node = detail::aligned_new<node>(detail::ALIGNMENT);

if constexpr (detail::has_max_size<Alloc>::value)
if constexpr (detail::has_max_size_v<Alloc>)
{
if (n > m_Node->Allocator.max_size())
return nullptr;
Expand Down Expand Up @@ -125,7 +130,10 @@ namespace ktl
* @param p The location in memory to deallocate
* @param n The size that was initially allocated
*/
void deallocate(void* p, size_type n) noexcept
void deallocate(void* p, size_type n) noexcept(
std::is_nothrow_destructible_v<node> &&
detail::has_nothrow_owns_v<Alloc> &&
detail::has_nothrow_deallocate_v<Alloc>)
{
KTL_ASSERT(p != nullptr);

Expand Down Expand Up @@ -165,7 +173,9 @@ namespace ktl
*/
template<typename T, typename... Args>
typename std::enable_if<detail::has_construct_v<Alloc, T*, Args...>, void>::type
construct(T* p, Args&&... args)
construct(T* p, Args&&... args) noexcept(
detail::has_nothrow_owns_v<Alloc> &&
detail::has_nothrow_construct_v<Alloc, T*, Args...>)
{
node* next = m_Node;
while (next)
Expand All @@ -179,6 +189,9 @@ namespace ktl
next = next->Next;
}

// If we ever get to this point, something has gone wrong with the internal allocators
KTL_ASSERT(false);

::new(p) T(std::forward<Args>(args)...);
}

Expand All @@ -189,7 +202,9 @@ namespace ktl
*/
template<typename T>
typename std::enable_if<detail::has_destroy_v<Alloc, T*>, void>::type
destroy(T* p)
destroy(T* p) noexcept(
detail::has_nothrow_owns_v<Alloc> &&
detail::has_nothrow_destroy_v<Alloc, T*>)
{
node* next = m_Node;
while (next)
Expand All @@ -203,6 +218,9 @@ namespace ktl
next = next->Next;
}

// If we ever get to this point, something has gone wrong with the internal allocators
KTL_ASSERT(false);

p->~T();
}
#pragma endregion
Expand All @@ -215,7 +233,8 @@ namespace ktl
*/
template<typename A = Alloc>
typename std::enable_if<detail::has_max_size_v<A>, size_type>::type
max_size() const noexcept
max_size() const
noexcept(detail::has_nothrow_max_size_v<A>)
{
return m_Node->Allocator.max_size();
}
Expand All @@ -226,6 +245,7 @@ namespace ktl
* @return Whether the allocator owns @p p
*/
bool owns(void* p) const
noexcept(detail::has_nothrow_owns_v<Alloc>)
{
node* next = m_Node;
while (next)
Expand All @@ -241,7 +261,8 @@ namespace ktl
#pragma endregion

private:
void release() noexcept
void release()
noexcept(std::is_nothrow_destructible_v<node>)
{
node* next = m_Node;
while (next)
Expand Down
58 changes: 36 additions & 22 deletions include/ktl/allocators/fallback.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,15 @@ namespace ktl
public:
typedef typename detail::get_size_type_t<P> size_type;

fallback() noexcept :
m_Primary(),
m_Fallback() {}
fallback() = default;

/**
* @brief Constructor for forwarding a single argument to the primary allocator
*/
template<typename Primary,
typename = std::enable_if_t<detail::can_construct_v<P, Primary>>>
explicit fallback(Primary&& primary) noexcept :
typename = std::enable_if_t<std::is_constructible_v<P, Primary>>>
explicit fallback(Primary&& primary)
noexcept(std::is_nothrow_constructible_v<P, Primary> && std::is_nothrow_default_constructible_v<F>) :
m_Primary(std::forward<Primary>(primary)),
m_Fallback() {}

Expand All @@ -47,9 +46,10 @@ namespace ktl
*/
template<typename Primary, typename Fallback,
typename = std::enable_if_t<
detail::can_construct_v<P, Primary> &&
detail::can_construct_v<F, Fallback>>>
explicit fallback(Primary&& primary, Fallback&& fallback) noexcept :
std::is_constructible_v<P, Primary> &&
std::is_constructible_v<F, Fallback>>>
explicit fallback(Primary&& primary, Fallback&& fallback)
noexcept(std::is_nothrow_constructible_v<P, Primary> && std::is_nothrow_constructible_v<F, Fallback>) :
m_Primary(std::forward<Primary>(primary)),
m_Fallback(std::forward<Fallback>(fallback)) {}

Expand All @@ -58,8 +58,9 @@ namespace ktl
*/
template<typename... Args,
typename = std::enable_if_t<
detail::can_construct_v<P, Args...>>>
explicit fallback(std::tuple<Args...>&& primary) noexcept :
std::is_constructible_v<P, Args...>>>
explicit fallback(std::tuple<Args...>&& primary)
noexcept(std::is_nothrow_constructible_v<P, Args...> && std::is_nothrow_default_constructible_v<F>) :
m_Primary(std::make_from_tuple<P>(std::forward<std::tuple<Args...>>(primary))),
m_Fallback() {}

Expand All @@ -68,32 +69,36 @@ namespace ktl
*/
template<typename... ArgsP, typename... ArgsF,
typename = std::enable_if_t<
detail::can_construct_v<P, ArgsP...>&&
detail::can_construct_v<F, ArgsF...>>>
explicit fallback(std::tuple<ArgsP...>&& primary, std::tuple<ArgsF...>&& fallback) noexcept :
std::is_constructible_v<P, ArgsP...>&&
std::is_constructible_v<F, ArgsF...>>>
explicit fallback(std::tuple<ArgsP...>&& primary, std::tuple<ArgsF...>&& fallback)
noexcept(std::is_nothrow_constructible_v<P, ArgsP...> && std::is_nothrow_constructible_v<F, ArgsF...>) :
m_Primary(std::make_from_tuple<P>(std::forward<std::tuple<ArgsP...>>(primary))),
m_Fallback(std::make_from_tuple<F>(std::forward<std::tuple<ArgsF...>>(fallback))) {}

fallback(const fallback&) noexcept = default;
fallback(const fallback&) = default;

fallback(fallback&&) noexcept = default;
fallback(fallback&&) = default;

fallback& operator=(const fallback&) noexcept = default;
fallback& operator=(const fallback&) = default;

fallback& operator=(fallback&&) noexcept = default;
fallback& operator=(fallback&&) = default;

bool operator==(const fallback& rhs) const noexcept
bool operator==(const fallback& rhs) const
noexcept(detail::has_nothrow_equal_v<P> && detail::has_nothrow_equal_v<F>)
{
return m_Primary == rhs.m_Primary && m_Fallback == rhs.m_Fallback;
}

bool operator!=(const fallback& rhs) const noexcept
bool operator!=(const fallback& rhs) const
noexcept(detail::has_nothrow_not_equal_v<P>&& detail::has_nothrow_not_equal_v<F>)
{
return m_Primary != rhs.m_Primary || m_Fallback != rhs.m_Fallback;
}

#pragma region Allocation
void* allocate(size_t n)
noexcept(detail::has_nothrow_allocate_v<P> && detail::has_nothrow_allocate_v<F>)
{
void* ptr = m_Primary.allocate(n);
if (!ptr)
Expand All @@ -102,6 +107,7 @@ namespace ktl
}

void deallocate(void* p, size_t n)
noexcept(detail::has_nothrow_deallocate_v<P>&& detail::has_nothrow_deallocate_v<F>)
{
if (m_Primary.owns(p))
{
Expand All @@ -116,7 +122,10 @@ namespace ktl
#pragma region Construction
template<typename T, typename... Args>
typename std::enable_if<detail::has_construct_v<P, T*, Args...> || detail::has_construct_v<F, T*, Args...>, void>::type
construct(T* p, Args&&... args)
construct(T* p, Args&&... args) noexcept(
(!detail::has_construct_v<P, T*, Args...> || detail::has_nothrow_construct_v<P, T*, Args...>) &&
(!detail::has_construct_v<F, T*, Args...> || detail::has_nothrow_construct_v<F, T*, Args...>) &&
std::is_nothrow_constructible_v<T, Args...>)
{
bool owned = m_Primary.owns(p);

Expand All @@ -143,7 +152,10 @@ namespace ktl

template<typename T>
typename std::enable_if<detail::has_destroy_v<P, T*> || detail::has_destroy_v<F, T*>, void>::type
destroy(T* p)
destroy(T* p) noexcept(
(!detail::has_destroy_v<P, T*> || detail::has_nothrow_destroy_v<P, T*>) &&
(!detail::has_destroy_v<F, T*> || detail::has_nothrow_destroy_v<F, T*>) &&
std::is_nothrow_destructible_v<T>)
{
bool owned = m_Primary.owns(p);

Expand Down Expand Up @@ -172,14 +184,16 @@ namespace ktl
#pragma region Utility
template<typename Primary = P, typename Fallback = F>
typename std::enable_if<detail::has_max_size_v<Primary> && detail::has_max_size_v<Fallback>, size_type>::type
max_size() const noexcept
max_size() const
noexcept(detail::has_nothrow_max_size_v<Primary> && detail::has_nothrow_max_size_v<Fallback>)
{
return (std::max)(m_Primary.max_size(), m_Fallback.max_size());
}

template<typename Primary = P, typename Fallback = F>
typename std::enable_if<detail::has_owns_v<Primary> && detail::has_owns_v<Fallback>, bool>::type
owns(void* p) const
noexcept(detail::has_nothrow_owns_v<Primary> && detail::has_nothrow_owns_v<Fallback>)
{
if (m_Primary.owns(p))
return true;
Expand Down
Loading

0 comments on commit c864b03

Please sign in to comment.