- Added missing functionality from C++ spec

This commit is contained in:
2025-08-20 14:00:52 -04:00
parent 494d766741
commit 037c62bf12
9 changed files with 97 additions and 43 deletions

View File

@@ -60,8 +60,12 @@ namespace fennec
/// \tparam ValueT value type /// \tparam ValueT value type
/// \tparam ElemV number of elements /// \tparam ElemV number of elements
template<typename ValueT, size_t ElemV> template<typename ValueT, size_t ElemV>
struct array struct array {
{
// Definitions =========================================================================================================
public:
using value_t = ValueT; ///< Alias for `ValueT`
// Public Members ====================================================================================================== // Public Members ======================================================================================================
/// \name Public Members /// \name Public Members
@@ -69,7 +73,7 @@ struct array
/// ///
/// \brief backing c-style array handle /// \brief backing c-style array handle
ValueT elements[ElemV]; value_t data[ElemV];
/// @} /// @}
@@ -101,9 +105,9 @@ struct array
/// ///
/// \copydetails array::operator[](size_t) const /// \copydetails array::operator[](size_t) const
constexpr ValueT& operator[](size_t i) { constexpr value_t& operator[](size_t i) {
assertd(i < ElemV, "Array Out of Bounds"); assertd(i < ElemV, "Array Out of Bounds");
return elements[i]; return data[i];
} }
/// ///
@@ -117,9 +121,37 @@ struct array
/// ///
/// \par Space-Complexity /// \par Space-Complexity
/// Constant /// Constant
constexpr const ValueT& operator[](size_t i) const { constexpr const value_t& operator[](size_t i) const {
assertd(i < ElemV, "Array Out of Bounds"); assertd(i < ElemV, "Array Out of Bounds");
return elements[i]; return data[i];
}
///
/// \brief Access the first element
/// \returns A reference to the element at `elements[0]`
constexpr value_t& front() {
return data[0];
}
///
/// \brief Const Access the first element
/// \returns A const-qualified reference to the element at `elements[0]`
constexpr const value_t& front() const {
return data[0];
}
///
/// \brief Access the first element
/// \returns A reference to the element at `elements[ElemV - 1]`
constexpr value_t& back() {
return data[ElemV - 1];
}
///
/// \brief Const Access the first element
/// \returns A const-qualified reference to the element at `elements[ElemV - 1]`
constexpr const value_t& back() const {
return data[ElemV - 1];
} }
/// @} /// @}
@@ -154,15 +186,15 @@ struct array
/// ///
/// \brief C++ Iterator Specification `begin()` /// \brief C++ Iterator Specification `begin()`
/// \returns A pointer to the first element of the array /// \returns A pointer to the first element of the array
constexpr ValueT* begin() { constexpr value_t* begin() {
return elements; return data;
} }
/// ///
/// \brief C++ Iterator Specification `end()` /// \brief C++ Iterator Specification `end()`
/// \returns A pointer to one after the end of the array /// \returns A pointer to one after the end of the array
constexpr ValueT* end() { constexpr value_t* end() {
return elements + ElemV; return data + ElemV;
} }
@@ -170,15 +202,15 @@ struct array
/// ///
/// \brief Const C++ Iterator Specification `begin()` /// \brief Const C++ Iterator Specification `begin()`
/// \returns A const-qualified pointer to the first element of the array /// \returns A const-qualified pointer to the first element of the array
constexpr const ValueT* begin() const { constexpr const value_t* begin() const {
return elements; return data;
} }
/// ///
/// \brief Const C++ Iterator Specification `end()` /// \brief Const C++ Iterator Specification `end()`
/// \returns A const-qualified pointer to one after the end of the array /// \returns A const-qualified pointer to one after the end of the array
constexpr const ValueT* end() const { constexpr const value_t* end() const {
return elements + ElemV; return data + ElemV;
} }
/// @} /// @}

View File

@@ -102,6 +102,16 @@ public:
, _size(0) { , _size(0) {
} }
///
/// \brief Alloc Constructor, initializes an empty deque with the specified allocator
/// \param alloc the allocator to copy
deque(const alloc_t& alloc)
: _alloc(alloc)
, _first(nullptr)
, _last(nullptr)
, _size(0) {
}
/// ///
/// \brief Copy Constructor /// \brief Copy Constructor
/// \param deque the deque to copy /// \param deque the deque to copy

View File

@@ -29,9 +29,12 @@ template <std::size_t I, typename T>
struct _tuple_leaf struct _tuple_leaf
{ {
template <typename ArgT> template <typename ArgT>
_tuple_leaf(ArgT&& arg) : value(fennec::forward<ArgT>(arg)) {} constexpr _tuple_leaf(ArgT&& arg) : value(fennec::forward<ArgT>(arg)) {}
~_tuple_leaf() = default; constexpr ~_tuple_leaf() = default;
constexpr _tuple_leaf& operator=(const _tuple_leaf&) = default;
constexpr _tuple_leaf& operator=(_tuple_leaf&&) noexcept = default;
T value; T value;
}; };
@@ -43,9 +46,14 @@ template <size_t...IndicesV, typename...TypesT>
struct _tuple<const_index_sequence<IndicesV...>, TypesT...> : _tuple_leaf<IndicesV, TypesT>... struct _tuple<const_index_sequence<IndicesV...>, TypesT...> : _tuple_leaf<IndicesV, TypesT>...
{ {
template <typename...ArgsT> template <typename...ArgsT>
_tuple(ArgsT&&... args) : _tuple_leaf<IndicesV, TypesT>(fennec::forward<ArgsT>(args))... {} constexpr _tuple(ArgsT&&... args)
: _tuple_leaf<IndicesV, TypesT>(fennec::forward<ArgsT>(args))... {
}
~_tuple() = default; constexpr _tuple& operator=(const _tuple&) = default;
constexpr _tuple& operator=(_tuple&&) noexcept = default;
constexpr ~_tuple() = default;
}; };
} }

View File

@@ -72,16 +72,15 @@ private:
struct node; struct node;
public: public:
///< Alias for the allocator type, rebound to list nodes /// \brief Alias for the allocator type, rebound to list nodes
using alloc_t = typename allocator_traits<Alloc>::template rebind<node>; using alloc_t = typename allocator_traits<Alloc>::template rebind<node>;
using value_t = TypeT; using value_t = TypeT; ///< Alias for the value type
using elem_t = node;
static constexpr size_t npos = -1; static constexpr size_t npos = -1; ///< Constant representing a non-existant position
class iterator; class iterator; ///< Iterator type for forward iteration over the list
class const_iterator; class const_iterator; ///< Iterator type for forward iteration over a constant list
// Constructors & Destructor =========================================================================================== // Constructors & Destructor ===========================================================================================

View File

@@ -81,15 +81,15 @@ struct map {
// Definitions ========================================================================================================= // Definitions =========================================================================================================
public: public:
struct key_hash; struct key_hash; ///< Hash for node keys
struct node_equals; struct key_equals; ///< Comparison for node keys
using key_t = KeyT; using key_t = KeyT; ///< The key type
using value_t = ValueT; using value_t = ValueT; ///< The value type
using elem_t = pair<KeyT, ValueT>; using elem_t = pair<KeyT, ValueT>; ///< then node type
using alloc_t = typename allocator_traits<Alloc>::template rebind<elem_t>; using alloc_t = typename allocator_traits<Alloc>::template rebind<elem_t>; ///< Rebinds the allocator type to nodes
using hash_t = Hash; using hash_t = Hash; ///< The hash type
using set_t = set<elem_t, key_hash, node_equals, alloc_t>; using set_t = set<elem_t, key_hash, key_equals, alloc_t>; ///< The underlying set
using iterator = set_t::iterator; using iterator = set_t::iterator; ///< Iterator type
// We only want to hash the key // We only want to hash the key
struct key_hash : hash_t { struct key_hash : hash_t {
@@ -99,7 +99,7 @@ public:
}; };
// We only want to compare the keys // We only want to compare the keys
struct node_equals : equality<KeyT> { struct key_equals : equality<KeyT> {
constexpr bool operator()(const elem_t& a, const elem_t& b) const { constexpr bool operator()(const elem_t& a, const elem_t& b) const {
return equality<KeyT>::operator()(a.first, b.first); return equality<KeyT>::operator()(a.first, b.first);
} }
@@ -248,7 +248,7 @@ public:
} }
/// ///
/// \brief Clears the set, destructing all elements /// \brief Clears the map destructing all elements
void clear() { void clear() {
_set.clear(); _set.clear();
} }

View File

@@ -550,7 +550,7 @@ private:
template<typename...ArgsT> template<typename...ArgsT>
constexpr void _insert(ArgsT&&...args) { constexpr void _insert(ArgsT&&...args) {
if (_size == 0 or static_cast<double>(_size) / capacity() >= _load) { // expand when full if (_size == 0 or static_cast<float>(_size) / capacity() >= _load) { // expand when full
_expand(); _expand();
} }
@@ -578,7 +578,7 @@ private:
equal_t _equal; equal_t _equal;
size_t _size; size_t _size;
size_t _sumpsl; size_t _sumpsl;
double _load; float _load;
}; };
} }

View File

@@ -159,20 +159,25 @@ public:
/// ///
/// \brief Move Insertion, inserts a copy of `x` into the pool /// \brief Emplacement, constructs a new object using `args...`
/// \param x the object to copy /// \param args The arguments to construct the new object with
/// \returns An integer corresponding to the id of the node /// \returns An integer corresponding to the id of the node
template<typename...ArgsT> template<typename...ArgsT>
constexpr size_t emplace(ArgsT&&...args) { constexpr size_t emplace(ArgsT&&...args) {
return this->_insert(fennec::forward<ArgsT>(args)...); return this->_insert(fennec::forward<ArgsT>(args)...);
} }
///
/// \brief Erase an object from the pool
/// \param i The id of the object
constexpr void erase(size_t i) { constexpr void erase(size_t i) {
_table[i] = nullopt; _table[i] = nullopt;
_freed.push_back(i); _freed.push_back(i);
--_size; --_size;
} }
/// @}
private: private:
dynarray<elem_t, AllocT> _table; dynarray<elem_t, AllocT> _table;
list<size_t> _freed; list<size_t> _freed;

View File

@@ -141,7 +141,7 @@ public:
/// ///
/// \brief Implicit Boolean Check, returns `true` when there is a value contained /// \brief Implicit Boolean Check, returns `true` when there is a value contained
constexpr operator bool() const { constexpr explicit operator bool() const {
return _set; return _set;
} }

View File

@@ -455,7 +455,7 @@ private:
template<typename...ArgsT> template<typename...ArgsT>
constexpr iterator _insert(ArgsT&&...args) { constexpr iterator _insert(ArgsT&&...args) {
if (_size == 0 or double(_size) / capacity() >= _load) { // expand when full if (_size == 0 or static_cast<float>(_size) / capacity() >= _load) { // expand when full
_expand(); _expand();
} }
@@ -484,7 +484,7 @@ private:
equal_t _equal; equal_t _equal;
size_t _size; size_t _size;
size_t _sumpsl; size_t _sumpsl;
double _load; float _load;
}; };
} }