#include #include #include #include #include class huffman_tree { std::string _value; std::shared_ptr _left; std::shared_ptr _right; public: huffman_tree(const std::string& value); huffman_tree(std::shared_ptr left, std::shared_ptr right); std::uint8_t value() const; std::shared_ptr left() const; std::shared_ptr right() const; bool is_leaf() const; }; struct huffman_probability { std::string bytes; double probability; std::shared_ptr tree; huffman_probability(const std::string& bytes, double probability); huffman_probability operator+(const huffman_probability& that) const; bool operator<(const huffman_probability& that) const; bool operator>(const huffman_probability& that) const; bool operator<=(const huffman_probability& that) const; bool operator>=(const huffman_probability& that) const; }; using coding = std::vector; using probability_list = std::vector; using probability_iterator = probability_list::iterator; using probability_const_iterator = probability_list::const_iterator; class huffman_table { std::unordered_map payload; void create_table(std::shared_ptr tree, coding path); public: huffman_table(std::shared_ptr tree); huffman_table(std::vector::const_iterator& coding_stream); huffman_table() = default; void insert(std::uint8_t byte, coding&& path); void encode(std::ostream& output) const; std::size_t size() const; std::unordered_map::iterator begin(); std::unordered_map::iterator end(); std::unordered_map::const_iterator begin() const; std::unordered_map::const_iterator end() const; const coding& operator[](std::uint8_t byte) const; }; std::shared_ptr create_tree(probability_list& probabilities); probability_list adapt_probabilities(const std::vector& input); void compress(const std::vector& input, std::ostream& output); void decompress(const std::vector& input, std::ostream& output);