Add array
This commit is contained in:
@ -6,6 +6,18 @@ package(
|
||||
default_applicable_licenses = ["//:license"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "array",
|
||||
hdrs = [
|
||||
"array.hpp",
|
||||
],
|
||||
deps = [
|
||||
"//asl/base",
|
||||
"//asl/types:span",
|
||||
],
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "box",
|
||||
hdrs = [
|
||||
@ -124,6 +136,16 @@ cc_test(
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "array_tests",
|
||||
srcs = ["array_tests.cpp"],
|
||||
deps = [
|
||||
"//asl/tests:utils",
|
||||
"//asl/testing",
|
||||
"//asl/types:array",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "box_tests",
|
||||
srcs = ["box_tests.cpp"],
|
||||
|
70
asl/types/array.hpp
Normal file
70
asl/types/array.hpp
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2025 Steven Le Rouzic
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "asl/base/assert.hpp"
|
||||
#include "asl/base/meta.hpp"
|
||||
#include "asl/base/utility.hpp"
|
||||
#include "asl/types/span.hpp"
|
||||
|
||||
namespace asl
|
||||
{
|
||||
|
||||
template<is_object T, int64_t kSize>
|
||||
requires (kSize > 0)
|
||||
struct array
|
||||
{
|
||||
T m_data[kSize];
|
||||
|
||||
[[nodiscard]] constexpr bool is_empty() const { return false; }
|
||||
|
||||
[[nodiscard]] constexpr int64_t size() const { return kSize; }
|
||||
|
||||
constexpr auto data(this auto&& self)
|
||||
{
|
||||
using return_type = un_ref_t<copy_cref_t<decltype(self), T>>*;
|
||||
return static_cast<return_type>(self.m_data);
|
||||
}
|
||||
|
||||
constexpr auto begin(this auto&& self)
|
||||
{
|
||||
return contiguous_iterator{self.data()};
|
||||
}
|
||||
|
||||
constexpr auto end(this auto&& self)
|
||||
{
|
||||
return contiguous_iterator{self.data() + kSize};
|
||||
}
|
||||
|
||||
template<int64_t kSpanSize>
|
||||
requires (kSpanSize == kSize || kSpanSize == dynamic_size)
|
||||
constexpr operator span<const T, kSpanSize>() const // NOLINT(*explicit*)
|
||||
{
|
||||
return as_span();
|
||||
}
|
||||
|
||||
template<int64_t kSpanSize>
|
||||
requires (kSpanSize == kSize || kSpanSize == dynamic_size)
|
||||
constexpr operator span<T, kSpanSize>() // NOLINT(*explicit*)
|
||||
{
|
||||
return as_span();
|
||||
}
|
||||
|
||||
constexpr auto as_span(this auto&& self)
|
||||
{
|
||||
using type = un_ref_t<copy_cref_t<decltype(self), T>>;
|
||||
return span<type, kSize>{self.data(), self.size()};
|
||||
}
|
||||
|
||||
constexpr auto&& operator[](this auto&& self, isize_t i)
|
||||
{
|
||||
ASL_ASSERT(i >= 0 && i <= self.size());
|
||||
return std::forward_like<decltype(self)>(std::forward<decltype(self)>(self).data()[i]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
} // namespace asl
|
||||
|
122
asl/types/array_tests.cpp
Normal file
122
asl/types/array_tests.cpp
Normal file
@ -0,0 +1,122 @@
|
||||
// Copyright 2025 Steven Le Rouzic
|
||||
//
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
|
||||
#include "asl/types/array.hpp"
|
||||
|
||||
#include "asl/testing/testing.hpp"
|
||||
#include "asl/tests/types.hpp"
|
||||
|
||||
static_assert(sizeof(asl::array<int32_t, 8>) == 32);
|
||||
|
||||
static_assert(asl::default_constructible<asl::array<int, 6>>);
|
||||
static_assert(asl::trivially_default_constructible<asl::array<int, 6>>);
|
||||
|
||||
static_assert(asl::default_constructible<asl::array<TrivialType, 6>>);
|
||||
static_assert(asl::trivially_default_constructible<asl::array<TrivialType, 6>>);
|
||||
static_assert(asl::trivially_copy_constructible<asl::array<TrivialType, 6>>);
|
||||
static_assert(asl::trivially_copy_assignable<asl::array<TrivialType, 6>>);
|
||||
static_assert(asl::trivially_move_constructible<asl::array<TrivialType, 6>>);
|
||||
static_assert(asl::trivially_move_assignable<asl::array<TrivialType, 6>>);
|
||||
|
||||
static_assert(asl::default_constructible<asl::array<TrivialTypeDefaultValue, 6>>);
|
||||
static_assert(!asl::trivially_default_constructible<asl::array<TrivialTypeDefaultValue, 6>>);
|
||||
|
||||
static_assert(asl::trivially_destructible<asl::array<int, 6>>);
|
||||
static_assert(asl::trivially_destructible<asl::array<TrivialType, 6>>);
|
||||
static_assert(!asl::trivially_destructible<asl::array<WithDestructor, 6>>);
|
||||
|
||||
static_assert(asl::copyable<asl::array<Copyable, 6>>);
|
||||
static_assert(!asl::copyable<asl::array<MoveableOnly, 6>>);
|
||||
static_assert(!asl::copyable<asl::array<Pinned, 6>>);
|
||||
|
||||
static_assert(asl::moveable<asl::array<Copyable, 6>>);
|
||||
static_assert(asl::moveable<asl::array<MoveableOnly, 6>>);
|
||||
static_assert(!asl::moveable<asl::array<Pinned, 6>>);
|
||||
|
||||
ASL_TEST(construct_default)
|
||||
{
|
||||
asl::array<int, 4> arr{};
|
||||
|
||||
ASL_TEST_EXPECT(static_cast<void*>(&arr) == static_cast<void*>(arr.data()));
|
||||
|
||||
ASL_TEST_EXPECT(arr[0] == 0);
|
||||
ASL_TEST_EXPECT(arr[1] == 0);
|
||||
ASL_TEST_EXPECT(arr[2] == 0);
|
||||
ASL_TEST_EXPECT(arr[3] == 0);
|
||||
|
||||
ASL_TEST_EXPECT(arr.data()[0] == 0); // NOLINT
|
||||
ASL_TEST_EXPECT(arr.data()[1] == 0); // NOLINT
|
||||
ASL_TEST_EXPECT(arr.data()[2] == 0); // NOLINT
|
||||
ASL_TEST_EXPECT(arr.data()[3] == 0); // NOLINT
|
||||
}
|
||||
|
||||
ASL_TEST(construct)
|
||||
{
|
||||
asl::array<int, 4> arr{10, 11, 12, 13};
|
||||
|
||||
ASL_TEST_EXPECT(arr[0] == 10);
|
||||
ASL_TEST_EXPECT(arr[1] == 11);
|
||||
ASL_TEST_EXPECT(arr[2] == 12);
|
||||
ASL_TEST_EXPECT(arr[3] == 13);
|
||||
|
||||
ASL_TEST_EXPECT(arr.data()[0] == 10); // NOLINT
|
||||
ASL_TEST_EXPECT(arr.data()[1] == 11); // NOLINT
|
||||
ASL_TEST_EXPECT(arr.data()[2] == 12); // NOLINT
|
||||
ASL_TEST_EXPECT(arr.data()[3] == 13); // NOLINT
|
||||
}
|
||||
|
||||
static_assert(asl::convertible_to<asl::array<int, 4>, asl::span<int, 4>>);
|
||||
static_assert(asl::convertible_to<asl::array<int, 4>, asl::span<int>>);
|
||||
|
||||
ASL_TEST(sized_span)
|
||||
{
|
||||
asl::array<int, 4> arr{10, 11, 12, 13};
|
||||
const asl::span<int, 4> s1 = arr;
|
||||
|
||||
ASL_TEST_EXPECT(s1.size() == 4);
|
||||
ASL_TEST_EXPECT(s1.data() == arr.data());
|
||||
ASL_TEST_EXPECT(s1[0] == 10);
|
||||
ASL_TEST_EXPECT(s1[1] == 11);
|
||||
ASL_TEST_EXPECT(s1[2] == 12);
|
||||
ASL_TEST_EXPECT(s1[3] == 13);
|
||||
}
|
||||
|
||||
ASL_TEST(unsized_span)
|
||||
{
|
||||
asl::array<int, 4> arr{10, 11, 12, 13};
|
||||
const asl::span<int> s2 = arr;
|
||||
|
||||
ASL_TEST_EXPECT(s2.size() == 4);
|
||||
ASL_TEST_EXPECT(s2[0] == 10);
|
||||
ASL_TEST_EXPECT(s2[1] == 11);
|
||||
ASL_TEST_EXPECT(s2[2] == 12);
|
||||
ASL_TEST_EXPECT(s2[3] == 13);
|
||||
}
|
||||
|
||||
ASL_TEST(iterator)
|
||||
{
|
||||
const asl::array<int, 4> arr{10, 11, 12, 13};
|
||||
|
||||
auto it = arr.begin();
|
||||
auto end = arr.end();
|
||||
|
||||
ASL_TEST_ASSERT(it != end);
|
||||
ASL_TEST_EXPECT(*it == 10);
|
||||
it++;
|
||||
|
||||
ASL_TEST_ASSERT(it != end);
|
||||
ASL_TEST_EXPECT(*it == 11);
|
||||
it++;
|
||||
|
||||
ASL_TEST_ASSERT(it != end);
|
||||
ASL_TEST_EXPECT(*it == 12);
|
||||
it++;
|
||||
|
||||
ASL_TEST_ASSERT(it != end);
|
||||
ASL_TEST_EXPECT(*it == 13);
|
||||
it++;
|
||||
|
||||
ASL_TEST_ASSERT(it == end);
|
||||
}
|
||||
|
Reference in New Issue
Block a user