Skip to content

Commit

Permalink
add queue raw view
Browse files Browse the repository at this point in the history
  • Loading branch information
Cyril Sharma committed Nov 12, 2024
1 parent 6671901 commit bc9a964
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 0 deletions.
7 changes: 7 additions & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,13 @@ cc_library(
copts = ["-std=c++20"],
)

cc_library(
name = "fixed_deque_raw_view",
hdrs = ["include/fixed_containers/fixed_deque_raw_view.hpp"],
includes = ["include"],
copts = ["-std=c++20"],
)

cc_library(
name = "fixed_queue",
hdrs = ["include/fixed_containers/fixed_queue.hpp"],
Expand Down
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ if(BUILD_TESTS)
add_test_dependencies(fixed_unordered_set_test)
add_executable(fixed_unordered_set_raw_view_test test/fixed_unordered_set_raw_view_test.cpp)
add_test_dependencies(fixed_unordered_set_raw_view_test)
add_executable(fixed_queue_raw_view_test test/fixed_queue_raw_view_test.cpp)
add_test_dependencies(fixed_queue_raw_view_test)
add_executable(fixed_stack_test test/fixed_stack_test.cpp)
add_test_dependencies(fixed_stack_test)
add_executable(fixed_queue_test test/fixed_queue_test.cpp)
Expand Down
107 changes: 107 additions & 0 deletions include/fixed_containers/fixed_deque_raw_view.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
#pragma once

#include "fixed_containers/forward_iterator.hpp"

#include <cstddef>

template <typename IndexType = std::size_t>
class FixedDequeRawView
{
public:
class ReferenceProvider
{
friend class FixedDequeRawView;

private:
const FixedDequeRawView* parent_;

IndexType current_idx_;

explicit constexpr ReferenceProvider(const FixedDoublyLinkedListRawView* parent) noexcept
: parent_{parent}
, current_idx_{static_cast<IndexType>(parent_->stat().start)}
{
}

public:
constexpr ReferenceProvider() noexcept
: parent_{nullptr}
, current_idx_{0}
{
}

constexpr void advance() noexcept {
current_idx_ = parent_->next_index(current_idx_);
}

[[nodiscard]] constexpr const std::byte* get() const noexcept
{
return parent_->value_at(current_idx_);
}

constexpr bool operator==(const ReferenceProvider& other) const noexcept = default;
};

private:
const std::byte* data_ptr_;
std::size_t elem_size_bytes_;
std::size_t elem_align_bytes_;
std::size_t max_elem_count_;

public:
using Iterator =
ForwardIterator<ReferenceProvider, ReferenceProvider, IteratorConstness::CONSTANT_ITERATOR>;
using iterator = Iterator;
using const_iterator = iterator;

FixedDequeRawView(const void* data_ptr,
std::size_t elem_size_bytes,
std::size_t elem_align_bytes,
std::size_t max_elem_count)
: data_ptr_{static_cast<const std::byte*>(data_ptr)}
, elem_size_bytes_{elem_size_bytes}
, elem_align_bytes_{elem_align_bytes}
, max_elem_count_{max_elem_count}
{
}

[[nodiscard]] Iterator begin() const { return std::next(Iterator{ReferenceProvider{this}}); }

[[nodiscard]] Iterator end() const { return Iterator{ReferenceProvider{this}}; }

[[nodiscard]] StartingIntegerAndDistance stat() const
{
// The bookkeeping fields are stored after the data in fixed_deque
return *reinterpret_cast<const StartingIntegerAndDistance*>(
std::next(data_ptr_, value_storage_size()));
}

[[nodiscard]] StartingIntegerAndDistance size() const { return stat().distance; }

public:

[[nodiscard]] constexpr const std::byte* value_at(IndexType index) const noexcept
{
return std::next(value_storage_start(),
static_cast<std::ptrdiff_t>(elem_size_bytes_ * index));
}

[[nodiscard]] constexpr const std::byte* value_storage_start() const noexcept
{
return data_ptr_;
}

[[nodiscard]] constexpr std::ptrdiff_t value_storage_size() const noexcept
{
// The size of the data portion of the queue.
std::size_t raw_size = max_elem_count_ * elem_size_bytes_;
return static_cast<std::ptrdiff_t>(raw_size);
}

[[nodiscard]] constexpr std::ptrdiff_t next_index(IndexType idx) const noexcept
{
auto stats = stat();
IndexType nidx = (stats.start + idx + 1) % max_elem_count_;
return nidx;
}
};
76 changes: 76 additions & 0 deletions test/fixed_deque_raw_view_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include "fixed_containers/fixed_deque_raw_view.hpp"

#include "mock_testing_types.hpp"

#include "fixed_containers/concepts.hpp"
#include "fixed_containers/fixed_deque.hpp"
#include "fixed_containers/map_entry.hpp"

#include <gtest/gtest.h>

#include <cstddef>
#include <iterator>
#include <ranges>

namespace fixed_containers
{
namespace
{
static_assert(std::forward_iterator<FixedUnorderedSetRawView::iterator>);
static_assert(std::ranges::forward_range<FixedUnorderedSetRawView>);

static_assert(sizeof(MapEntry<int, EmptyValue>) == sizeof(int));
static_assert(sizeof(MapEntry<char, EmptyValue>) == sizeof(char));
static_assert(sizeof(MapEntry<MockAligned64, EmptyValue>) == sizeof(MockAligned64));

template <typename T>
T get_from_ptr(const std::byte* ptr)
{
return *reinterpret_cast<const T*>(ptr);
}

template <typename Elem>
void test_and_increment(auto& map_it, auto& view_it)
{
EXPECT_EQ(*map_it, get_from_ptr<Elem>(*view_it));
++map_it;
++view_it;
}
} // namespace

TEST(FixedUnorderedSetRawView, IntSet)
{
auto dq = make_fixed_deque<int>({1, 2, 3, 5, 8, 13});
const FixedDequeRawView view{&dq, sizeof(int), alignof(int), dq.max_size()};
EXPECT_EQ(set.size(), view.size());
auto set_it = set.begin();
auto view_it = view.begin();
for (std::size_t i = 0; i < set.size(); i++)
{
test_and_increment<int>(set_it, view_it);
}
EXPECT_EQ(set_it, set.end());
EXPECT_EQ(view_it, view.end());
}

// TEST(FixedUnorderedsetRawView, StructSet)
// {
// FixedUnorderedSet<MockAligned64, 10> set{};
// set.insert({21});
// set.insert({34});
// set.insert({55});

// const FixedUnorderedSetRawView view{&set, sizeof(MockAligned64), alignof(MockAligned64), 10};

// EXPECT_EQ(set.size(), view.size());
// auto set_it = set.begin();
// auto view_it = view.begin();
// for (std::size_t i = 0; i < set.size(); i++)
// {
// test_and_increment<MockAligned64>(set_it, view_it);
// }
// EXPECT_EQ(set_it, set.end());
// EXPECT_EQ(view_it, view.end());
// }

} // namespace fixed_containers

0 comments on commit bc9a964

Please sign in to comment.