-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Cyril Sharma
committed
Nov 12, 2024
1 parent
6671901
commit bc9a964
Showing
4 changed files
with
192 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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; | ||
} | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |