-
Notifications
You must be signed in to change notification settings - Fork 38
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
1 parent
0298e75
commit 26ff0bf
Showing
8 changed files
with
454 additions
and
39 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
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,187 @@ | ||
#pragma once | ||
|
||
#include "fixed_containers/assert_or_abort.hpp" | ||
#include "fixed_containers/fixed_red_black_tree_nodes.hpp" | ||
#include "fixed_containers/fixed_red_black_tree_types.hpp" | ||
#include "fixed_containers/fixed_red_black_tree_view.hpp" | ||
|
||
#include <cstddef> | ||
#include <iterator> | ||
|
||
namespace fixed_containers | ||
{ | ||
|
||
class FixedMapRawView | ||
{ | ||
using Compactness = fixed_red_black_tree_detail::RedBlackTreeNodeColorCompactness; | ||
using StorageType = fixed_red_black_tree_detail::RedBlackTreeStorageType; | ||
using NodeIndex = fixed_red_black_tree_detail::NodeIndex; | ||
|
||
public: | ||
class Iterator | ||
{ | ||
public: | ||
|
||
// I use Entry so we can match UnorderedMapRawView's API where, | ||
// *it returns an object with .key() and .value() methods. | ||
class Entry { | ||
|
||
private: | ||
FixedRedBlackTreeRawView::Iterator base_iterator_; | ||
std::size_t value_offset_; | ||
|
||
public: | ||
friend class Iterator; | ||
Entry(const std::byte* ptr, | ||
std::size_t value_offset_bytes, | ||
std::size_t element_size_bytes, | ||
std::size_t max_size_bytes, | ||
Compactness compactness, | ||
StorageType storage_type, | ||
bool end = false) noexcept: | ||
base_iterator_(ptr, | ||
element_size_bytes, | ||
max_size_bytes, | ||
compactness, | ||
storage_type, | ||
end), | ||
value_offset_(value_offset_bytes) {} | ||
|
||
Entry(): base_iterator_(), value_offset_(0) {} | ||
|
||
[[nodiscard]] const std::byte* key() const { return *base_iterator_; } | ||
|
||
[[nodiscard]] const std::byte* value() const | ||
{ | ||
return std::next(*base_iterator_, static_cast<std::ptrdiff_t>(value_offset_)); | ||
} | ||
|
||
}; | ||
|
||
private: | ||
Entry entry_; | ||
|
||
public: | ||
using value_type = Entry; | ||
using difference_type = std::ptrdiff_t; | ||
using pointer = value_type*; | ||
using const_pointer = const value_type*; | ||
using reference = value_type&; | ||
using const_reference = const value_type&; | ||
using iterator_category = std::forward_iterator_tag; | ||
|
||
// Constructor that initializes the base iterator | ||
Iterator(const std::byte* ptr, | ||
std::size_t key_size_bytes, | ||
std::size_t key_align_bytes, | ||
std::size_t value_size_bytes, | ||
std::size_t value_align_bytes, | ||
std::size_t max_size_bytes, | ||
Compactness compactness, | ||
StorageType storage_type, | ||
bool end = false) noexcept | ||
: entry_(ptr, | ||
align_up(key_size_bytes, value_align_bytes), | ||
align_up(align_up(key_size_bytes, value_align_bytes) + value_size_bytes, key_align_bytes), | ||
max_size_bytes, | ||
compactness, | ||
storage_type, | ||
end) | ||
{ | ||
} | ||
|
||
Iterator() noexcept: entry_() {} | ||
Iterator(const Iterator&) noexcept = default; | ||
Iterator(Iterator&&) noexcept = default; | ||
Iterator& operator=(const Iterator&) noexcept = default; | ||
Iterator& operator=(Iterator&&) noexcept = default; | ||
|
||
Iterator& operator++() | ||
{ | ||
++entry_.base_iterator_; | ||
return *this; | ||
} | ||
|
||
Iterator operator++(int) & noexcept | ||
{ | ||
Iterator tmp = *this; | ||
++entry_.base_iterator_; | ||
return tmp; | ||
} | ||
|
||
const_reference operator*() const { return entry_; } | ||
|
||
const_pointer operator->() const { return &entry_; } | ||
|
||
bool operator==(const Iterator& other) const | ||
{ | ||
return entry_.base_iterator_ == other.entry_.base_iterator_; | ||
} | ||
|
||
bool operator!=(const Iterator& other) const { return !(*this == other); } | ||
|
||
[[nodiscard]] std::size_t size() const { return entry_.base_iterator_.size(); } | ||
}; | ||
|
||
private: | ||
const std::byte* tree_ptr_; | ||
const std::size_t key_size_bytes_; | ||
const std::size_t key_align_bytes_; | ||
const std::size_t value_size_bytes_; | ||
const std::size_t value_align_bytes_; | ||
const std::size_t max_size_bytes_; | ||
const Compactness compactness_; | ||
const StorageType storage_type_; | ||
|
||
public: | ||
FixedMapRawView(const void* tree_ptr, | ||
std::size_t key_size_bytes, | ||
std::size_t key_align_bytes, | ||
std::size_t value_size_bytes, | ||
std::size_t value_align_bytes, | ||
std::size_t max_size_bytes, | ||
Compactness compactness, | ||
StorageType storage_type) | ||
: tree_ptr_{reinterpret_cast<const std::byte*>(tree_ptr)} | ||
, key_size_bytes_{key_size_bytes} | ||
, key_align_bytes_{key_align_bytes} | ||
, value_size_bytes_{value_size_bytes} | ||
, value_align_bytes_{value_align_bytes} | ||
, max_size_bytes_{max_size_bytes} | ||
, compactness_{compactness} | ||
, storage_type_{storage_type} | ||
{ | ||
// Needed until FixedRedBlackTreeRawView supports types with alignment >= 8. | ||
// Currently, it tacititly presumes alignment will be <= 8 for the keys and values. | ||
assert_or_abort(std::max(value_align_bytes, key_align_bytes) <= 8); | ||
} | ||
|
||
[[nodiscard]] Iterator begin() const | ||
{ | ||
return Iterator(tree_ptr_, | ||
key_size_bytes_, | ||
key_align_bytes_, | ||
value_size_bytes_, | ||
value_align_bytes_, | ||
max_size_bytes_, | ||
compactness_, | ||
storage_type_); | ||
} | ||
|
||
[[nodiscard]] Iterator end() const | ||
{ | ||
return Iterator(tree_ptr_, | ||
key_size_bytes_, | ||
key_align_bytes_, | ||
value_size_bytes_, | ||
value_align_bytes_, | ||
max_size_bytes_, | ||
compactness_, | ||
storage_type_, | ||
true); | ||
} | ||
|
||
[[nodiscard]] std::size_t size() const { return end().size(); } | ||
}; | ||
|
||
} // namespace fixed_containers |
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,43 @@ | ||
#pragma once | ||
|
||
#include <cstddef> | ||
#include <iterator> | ||
|
||
class MapEntryRawView | ||
{ | ||
private: | ||
const std::byte* base_ptr_; | ||
const std::ptrdiff_t value_offs_; | ||
|
||
public: | ||
static constexpr std::ptrdiff_t get_value_offs(std::size_t key_size, | ||
std::size_t /*key_alignment*/, | ||
std::size_t /*value_size*/, | ||
std::size_t value_alignment) | ||
{ | ||
std::size_t value_offs = key_size; | ||
// align the value start addr to the correct alignment | ||
if (value_offs % value_alignment != 0) | ||
{ | ||
value_offs += value_alignment - value_offs % value_alignment; | ||
} | ||
return static_cast<std::ptrdiff_t>(value_offs); | ||
} | ||
|
||
public: | ||
MapEntryRawView(const void* ptr, | ||
std::size_t key_size, | ||
std::size_t key_alignment, | ||
std::size_t value_size, | ||
std::size_t value_alignment) | ||
: base_ptr_{reinterpret_cast<const std::byte*>(ptr)} | ||
, value_offs_{get_value_offs(key_size, key_alignment, value_size, value_alignment)} | ||
{ | ||
} | ||
|
||
[[nodiscard]] const std::byte* key() const { return base_ptr_; } | ||
|
||
[[nodiscard]] const std::byte* value() const { return std::next(base_ptr_, value_offs_); } | ||
|
||
[[nodiscard]] std::ptrdiff_t value_offset() const { return value_offs_; } | ||
}; |
Oops, something went wrong.