Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .github/workflows/check_copyright_license_headers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ jobs:
chmod +x ./scripts/check_copyright_license_headers.sh
./scripts/check_copyright_license_headers.sh
env:
HEADER: "// Copyright 2025 Atalante.\n// Licensed under MIT."
GITHUB_BASE_REF: ${{github.base_ref}}
GITHUB_HEAD_REF: ${{github.head_ref}}
GITHUB_TREE_URL: ${{github.server_url}}/${{github.repository}}/tree/${{github.head_ref}}
File renamed without changes.
11 changes: 6 additions & 5 deletions Base/Base.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2025 Atalante.
// Copyright 2025 Atalante.
// Licensed under MIT.

#pragma once
Expand All @@ -9,13 +9,14 @@

#include "Context.hpp"
#include "Macros.hpp"
#include "Types.hpp"

#include "Aliases.hpp"
#include "Limits.hpp"
#include "Cast.hpp"
#include "Utilities.hpp"
#include "Bit.hpp"

#include "buffer.hpp"
#include "str8.hpp"
#include "Types/sequence.hpp"
#include "Types/view.hpp"

#if OPERATING_SYSTEM == OPERATING_SYSTEM_WINDOWS
#include <Windows.h>
Expand Down
8 changes: 7 additions & 1 deletion Base/Context.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2025 Atalante.
// Copyright 2025 Atalante.
// Licensed under MIT.

#pragma once
Expand Down Expand Up @@ -57,4 +57,10 @@
#define ARCHITECTURE ARCHITECTURE_INTEL_X86
#else
#define ARCHITECTURE ARCHITECTURE_OTHER
#endif

#if STANDARD >= STANDARD_CPP17
#define CONSTEXPR_CPP17 constexpr
#else
#define CONSTEXPR_CPP17
#endif
109 changes: 109 additions & 0 deletions Base/Types/base_sequence.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// Copyright 2025 Atalante.
// Licensed under MIT.

#pragma once

namespace ProjectA {
// TODO(upgrade): Allocate from arena.
template<typename T>
class base_sequence {
private:
static T* allocate(uint64 count) {
return new T[count]();
}

static void free(const T* data) {
delete[] data;
}

public:
base_sequence<T>() = default;

explicit base_sequence<T>(uint64 count) :
_count(count),
_data(allocate(_count))
{}

base_sequence<T>(std::initializer_list<T> list) :
base_sequence<T>(list.size())
{
copy(list.begin(), list.end(), _data);
}

base_sequence<T>(const base_sequence<T>& sequence) :
base_sequence<T>(sequence._count)
{
copy(sequence.begin(), sequence.end(), _data);
}

base_sequence<T>(base_sequence<T>&& sequence) noexcept :
_count(sequence._count)
{
_data = sequence._data;

sequence._count = 0;
sequence._data = nullptr;
}

~base_sequence<T>() {
free(_data);
}

void operator=(const base_sequence<T>& sequence) {
free(_data);

_count = sequence._count;
_data = allocate(_count);

copy(sequence.begin(), sequence.end(), _data);
}

void operator=(base_sequence<T>&& sequence) noexcept {
ASSERT(_data != sequence._data);

_count = sequence._count;
_data = sequence._data;

sequence._count = 0;
sequence._data = nullptr;
}

uint64 count() const {
return _count;
}

const T& operator[](uint64 index) const {
// TODO: Always allow 0?
ASSERT(index < _count);

return _data[index];
}

T& operator[](uint64 index) {
// TODO: Always allow 0?
ASSERT(index < _count);

return _data[index];
}

const T* begin() const {
return _data;
}

T* begin() {
return _data;
}

const T* end() const {
return _data + _count;
}

T* end() {
return _data + _count;
}

protected:
uint64 _count = 0;
T* _data = nullptr;
};
}
44 changes: 44 additions & 0 deletions Base/Types/base_view.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright 2025 Atalante.
// Licensed under MIT.

#pragma once

namespace ProjectA {
template<typename T>
class base_view {
public:
explicit base_view() = default;

base_view<T>(const base_sequence<T>& sequence) :
_count(sequence.count()),
_data(sequence.begin())
{}

constexpr explicit base_view<T>(const char8* data, uint64 count) :
_count(count),
_data(data)
{}

uint64 count() const {
return _count;
}

const T& operator[](uint64 index) const {
ASSERT(index < _count);

return _data[index];
}

const T* begin() const {
return _data;
}

const T* end() const {
return _data + _count;
}

protected:
const uint64 _count = 0;
const T* _data = nullptr;
};
}
46 changes: 46 additions & 0 deletions Base/Types/sequence.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// Copyright 2025 Atalante.
// Licensed under MIT.

#pragma once

#include "Types/base_sequence.hpp"
#include "Types/base_view.hpp"

namespace ProjectA {
// A container that encapsulates a dynamic size array.
// Unlike `std::vector<T>`, `sequence<T>` is not resizeable.
// It *should* be used when the number of elements is known at runtime, before creating the sequence.
//
// NOTE: `T` **must** expose a default constructor.
template<typename T>
class sequence : public base_sequence<T> {
public:
using base_sequence<T>::base_sequence;
};

template<>
class sequence<char8> : public base_sequence<char8> {
public:
using base_sequence<char8>::base_sequence;

explicit sequence<char8>(const char8* data, uint64 count) :
sequence<char8>(count + 1)
{
_count -= 1;

copy(data, data + _count, _data);
}

sequence<char8>(const char8* data) :
sequence<char8>(data, std::strlen(data))
{}

sequence<char8>(base_view<char8> view) :
sequence<char8>(&view[0], view.count())
{}

sequence<char8>(const sequence<char8>& sequence) :
sequence(sequence.begin(), sequence.count())
{}
};
}
64 changes: 64 additions & 0 deletions Base/Types/view.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Copyright 2025 Atalante.
// Licensed under MIT.

#pragma once

#include "Types/base_view.hpp"

namespace ProjectA {
template<typename T>
class view : public base_view<T> {
public:
using base_view<T>::base_view;
};

template<>
class view<char8> : public base_view<char8> {
public:
using base_view<char8>::base_view;

// TODO: Add support for versions below C++17.
CONSTEXPR_CPP17 view<char8>(const char8* data) :
view<char8>(data, std::char_traits<char8>::length(data))
{}

uint64 find(char8 character, uint64 characterOffset) const {
while (characterOffset < count()) {
if (_data[characterOffset] == character) {
break;
}

characterOffset += 1;
}

return characterOffset;
}

uint64 find(view<char8> view, uint64 characterOffset) const {
uint64 characterIndex;
uint64 viewCharacterIndex;

while (characterOffset < count()) {
if (view.count() > count() - characterOffset) {
return count();
}

characterIndex = characterOffset;
viewCharacterIndex = 0;

while (_data[characterIndex] == view[viewCharacterIndex]) {
characterIndex += 1;
viewCharacterIndex += 1;

if (characterIndex >= count() || viewCharacterIndex >= view.count()) {
return characterOffset;
}
}

characterOffset += 1;
}

return characterOffset;
}
};
}
11 changes: 11 additions & 0 deletions Base/Utilities.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright 2025 Atalante.
// Licensed under MIT.

#pragma once

namespace ProjectA {
template<typename T>
inline void copy(const T* sourceBegin, const T* sourceEnd, T* destination) {
std::copy(sourceBegin, sourceEnd, destination);
}
}
Loading