<commit_before>#ifndef Trie_
#define Trie_

#include <iostream>
#include <functional>
#include <list>

#define BRANCH_CNT 26

class Trie {
   private:
      class Node {
         public:
            bool valid;
            Node **children;
            Node *parent;
            int childrenCnt;
            Node() : parent{nullptr} {
               children = new Node*[BRANCH_CNT];
               for(int i=0; i<BRANCH_CNT; i++)
                 children[i] = nullptr;
               valid = false;
               childrenCnt = 0;
            }
            ~Node() {
               //delete[] *children;
               delete[] children;
            }
      };
      Node *head;

      void inOrder(Node *x, std::string s, std::function<void(std::string)> f);
      void clear(Node *t);

   public:
      Trie();
      Trie(const Trie&);
      Trie(Trie&&);
      Trie& operator=(const Trie&);
      Trie& operator=(Trie&&);
      ~Trie() {
        clear(head);
      }
      bool insert(std::string x);
      bool del(std::string x);
      bool exists(std::string x);
      bool partialMatch(std::string x);
      void print();
      // returns list of of all valid std::strings in the trie
      std::list<std::string> getList();
};

/*********** Trie Implementation *************/

Trie::Trie() : head{new Node} {}

// copy constructor
Trie::Trie(const Trie& other) : head{new Node} {
  inOrder(other.head, "", [this](std::string s){insert(s);});
}

// move constructor
Trie::Trie(Trie&& other) : head{new Node} {
  head = other.head;
  other.head = nullptr;
}

Trie& Trie::operator=(const Trie& other) {
  if(head != other.head) {
    if(head) {
      clear(head);
    }
    head = new Node;
    inOrder(other.head, "", [this](std::string s){ insert(s); });
  }
  return *this;
}

Trie& Trie::operator=(Trie&& other) {
  if(head != other.head) {
    if(head) {
      clear(head);
    }
    head = other.head;
    other.head = nullptr;
  }
}

void Trie::clear(Trie::Node *t) {
  if(t != NULL) {
    for(int i=0; i<BRANCH_CNT; i++) {
      clear(t->children[i]);
    }
    delete t;
  }
}

bool Trie::insert(std::string x) {
  // if head is a nullptr, someone must have moved using std::move
  if(!head)
    head = new Node;

  Node *tmp = head;
  int index;
  for( int i=0; i<x.length(); i++ ) {
    index = (int)tolower(x[i]) - 97;
    if( index < 0 || index >= BRANCH_CNT )
       return false;
    if( tmp->children[index] ) {
       tmp = tmp->children[index];
    } else {
       tmp->children[index] = new Node;
       tmp->children[index]->parent = tmp;
       tmp->childrenCnt++;
       if( !tmp->children[index] ) {
          return false;
       }<commit_msg>Added return statement for move assignment operator. Previously wan't returning anything.<commit_after>#ifndef Trie_
#define Trie_

#include <iostream>
#include <functional>
#include <list>

#define BRANCH_CNT 26

class Trie {
   private:
      class Node {
         public:
            bool valid;
            Node **children;
            Node *parent;
            int childrenCnt;
            Node() : parent{nullptr} {
               children = new Node*[BRANCH_CNT];
               for(int i=0; i<BRANCH_CNT; i++)
                 children[i] = nullptr;
               valid = false;
               childrenCnt = 0;
            }
            ~Node() {
               //delete[] *children;
               delete[] children;
            }
      };
      Node *head;

      void inOrder(Node *x, std::string s, std::function<void(std::string)> f);
      void clear(Node *t);

   public:
      Trie();
      Trie(const Trie&);
      Trie(Trie&&);
      Trie& operator=(const Trie&);
      Trie& operator=(Trie&&);
      ~Trie() {
        clear(head);
      }
      bool insert(std::string x);
      bool del(std::string x);
      bool exists(std::string x);
      bool partialMatch(std::string x);
      void print();
      // returns list of of all valid std::strings in the trie
      std::list<std::string> getList();
};

/*********** Trie Implementation *************/

Trie::Trie() : head{new Node} {}

// copy constructor
Trie::Trie(const Trie& other) : head{new Node} {
  inOrder(other.head, "", [this](std::string s){insert(s);});
}

// move constructor
Trie::Trie(Trie&& other) : head{new Node} {
  head = other.head;
  other.head = nullptr;
}

Trie& Trie::operator=(const Trie& other) {
  if(head != other.head) {
    if(head) {
      clear(head);
    }
    head = new Node;
    inOrder(other.head, "", [this](std::string s){ insert(s); });
  }
  return *this;
}

Trie& Trie::operator=(Trie&& other) {
  if(head != other.head) {
    if(head) {
      clear(head);
    }
    head = other.head;
    other.head = nullptr;
  }
  return *this;
}

void Trie::clear(Trie::Node *t) {
  if(t != NULL) {
    for(int i=0; i<BRANCH_CNT; i++) {
      clear(t->children[i]);
    }
    delete t;
  }
}

bool Trie::insert(std::string x) {
  // if head is a nullptr, someone must have moved using std::move
  if(!head)
    head = new Node;

  Node *tmp = head;
  int index;
  for( int i=0; i<x.length(); i++ ) {
    index = (int)tolower(x[i]) - 97;
    if( index < 0 || index >= BRANCH_CNT )
       return false;
    if( tmp->children[index] ) {
       tmp = tmp->children[index];
    } else {
       tmp->children[index] = new Node;
       tmp->children[index]->parent = tmp;
       tmp->childrenCnt++;
       if( !tmp->children[index] ) {
          return false;
       }
{'fraction_non_alphanumeric': 0.16715704303052592, 'fraction_numerical': 0.0033100404560500183, 'mean_word_length': 2.1751313485113837, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 31, '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': '6903822', 'n_tokens_mistral': 1858, 'n_tokens_neox': 1826, 'n_words': 442}