<commit_before>
#ifndef FYP_MAPS_BUCKET_HPP
#define FYP_MAPS_BUCKET_HPP

namespace drt {

    template<typename Key, typename Val, class Hash = std::hash<Key>,
            size_t S = 4088 / sizeof(std::pair<Key, Val>) >
    class Hashmap;

namespace drtx {

    template<typename Key, typename Val, class Hash, size_t S>
    class BucketIterator;

    template<typename T>
    struct _bNode {
        /* Main holder of data in bucket list. Every node except the
               final one in the list will be a BNode. */

        // DO NOT REORDER THESE!
        T element;
        void *next = nullptr;

        _bNode() = default;
        _bNode(T &&e) noexcept : element(std::move(e)) {}
        ~_bNode() = default;
    };

    template<typename Key, typename Val, class Hash, size_t S>
    struct _bucketBase {

        using value_type  =  typename Hashmap<Key, Val, Hash, S>::value_type;
        using bNode       =  _bNode<value_type>;
        using iterator    =  BucketIterator<Key, Val, Hash, S>;
        // misc return type alias for brevity
        using bool_ptr    =  std::pair<bool, bNode*>;

        void *head = nullptr;

        _bucketBase() = default;
        ~_bucketBase() = default;

        /**
         * Searches for an element with key = k.
         *
         * @param  k The key to search for.
         * @return A value_type, if the key is matched; otherwise a nullptr.
         */
        value_type* search(const Key &k) const {
            iterator it = begin();

            while (it.current) {
                value_type *element = it.current_element();

                if (element->first == k) {
                    return element;
                }
                ++it;
            }

            return nullptr;
        }

        /**
         * Inserts an element as the head of the list. Should only be used on
         * empty buckets.
         *
         * @param element Pointer to an element.
         */
        void insert_node(value_type *element) {
            head = flag(element, 1);
        }

        /**
         * Inserts a node at the beginning of the list. Should not be used on
         * an empty bucket.
         *
         * @param node Pointer to a node.
         */
        void insert_node(bNode *node) {
            node->next = head;
            head = flag(node, 3);
        }

        /**
         * Removes a node from the list. Note that this doesn't destroy the
         * object; that is taken care of in Hashmap. The contents of the
         * return type inform Hashmap on what to do next.
         */
        bool_ptr remove_node(void *to_remove) {
            if (isSingle()) {
                head = nullptr;
                return bool_ptr(true, nullptr);
            }

            if (isHead(to_remove)) {
                remove_first(reinterpret_cast<bNode*>(to_remove));
                return bool_ptr(false, nullptr);
            }

            // element to remove is somewhere past the first node
            bNode *b = node_before(to_remove);
            // to_remove might be the element at the end of the list
            if (isTail(b->next)) {
                remove_tail(b);
                // b needs to be moved from node -> element
                return bool_ptr(true, b);
            }

            bNode *node_to_remove = reinterpret_cast<bNode*>(b->next);
            b->next = node_to_remove->next;
            node_to_remove->next = nullptr;

            return bool_ptr(false, nullptr);<commit_msg>FIX - Don't cast dirty pointers!<commit_after>
#ifndef FYP_MAPS_BUCKET_HPP
#define FYP_MAPS_BUCKET_HPP

namespace drt {

    template<typename Key, typename Val, class Hash = std::hash<Key>,
            size_t S = 4088 / sizeof(std::pair<Key, Val>) >
    class Hashmap;

namespace drtx {

    template<typename Key, typename Val, class Hash, size_t S>
    class BucketIterator;

    template<typename T>
    struct _bNode {
        /* Main holder of data in bucket list. Every node except the
               final one in the list will be a BNode. */

        // DO NOT REORDER THESE!
        T element;
        void *next = nullptr;

        _bNode() = default;
        _bNode(T &&e) noexcept : element(std::move(e)) {}
        ~_bNode() = default;
    };

    template<typename Key, typename Val, class Hash, size_t S>
    struct _bucketBase {

        using value_type  =  typename Hashmap<Key, Val, Hash, S>::value_type;
        using bNode       =  _bNode<value_type>;
        using iterator    =  BucketIterator<Key, Val, Hash, S>;
        // misc return type alias for brevity
        using bool_ptr    =  std::pair<bool, bNode*>;

        void *head = nullptr;

        _bucketBase() = default;
        ~_bucketBase() = default;

        /**
         * Searches for an element with key = k.
         *
         * @param  k The key to search for.
         * @return A value_type, if the key is matched; otherwise a nullptr.
         */
        value_type* search(const Key &k) const {
            iterator it = begin();

            while (it.current) {
                value_type *element = it.current_element();

                if (element->first == k) {
                    return element;
                }
                ++it;
            }

            return nullptr;
        }

        /**
         * Inserts an element as the head of the list. Should only be used on
         * empty buckets.
         *
         * @param element Pointer to an element.
         */
        void insert_node(value_type *element) {
            head = flag(element, 1);
        }

        /**
         * Inserts a node at the beginning of the list. Should not be used on
         * an empty bucket.
         *
         * @param node Pointer to a node.
         */
        void insert_node(bNode *node) {
            node->next = head;
            head = flag(node, 3);
        }

        /**
         * Removes a node from the list. Note that this doesn't destroy the
         * object; that is taken care of in Hashmap. The contents of the
         * return type inform Hashmap on what to do next.
         */
        bool_ptr remove_node(void *to_remove) {
            if (isSingle()) {
                head = nullptr;
                return bool_ptr(true, nullptr);
            }

            if (isHead(to_remove)) {
                remove_first(reinterpret_cast<bNode*>(to_remove));
                return bool_ptr(false, nullptr);
            }

            // element to remove is somewhere past the first node
            bNode *b = node_before(to_remove);
            // to_remove might be the element at the end of the list
            if (isTail(b->next)) {
                remove_tail(b);
                // b needs to be moved from node -> element
                return bool_ptr(true, b);
            }

            // to_remove is a node
            bNode *node_to_remove = reinterpret_cast<bNode*>(to_remove);
            b->next = node_to_remove->next;
            node_to_remove->next = nullptr;

            return bool_ptr(false, nullptr);
{'fraction_non_alphanumeric': 0.09141156462585034, 'fraction_numerical': 0.0017006802721088435, 'mean_word_length': 1.5689843465598836, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2339309', 'n_tokens_mistral': 2013, 'n_tokens_neox': 1918, 'n_words': 643}