Skip to content

Instantly share code, notes, and snippets.

@dgodfrey206
Created April 18, 2016 00:01
Show Gist options
  • Save dgodfrey206/9110784fb8f08ad1035b56ebae94e2b1 to your computer and use it in GitHub Desktop.
Save dgodfrey206/9110784fb8f08ad1035b56ebae94e2b1 to your computer and use it in GitHub Desktop.
Morse code translator
#include <algorithm>
#include <streambuf>
#include <iostream>
#include <fstream>
#include <stdexcept>
#include <utility>
#include <string>
#include <vector>
#include <cctype>
#include <memory>
namespace parser {
class base_pair
{
public:
using pair_type = std::pair<char, std::string>;
using key_type = pair_type::first_type;
using value_type = pair_type::second_type;
friend bool operator==(const base_pair&, key_type);
friend bool operator==(key_type, const base_pair&);
friend bool operator==(const value_type&, const base_pair&);
friend bool operator==(const base_pair&, const value_type&);
key_type get_first()
{
return p.first;
}
value_type get_second()
{
return p.second;
}
base_pair(key_type x, value_type y) : p(std::move(x), std::move(y)) { }
private:
pair_type p;
};
class morse
{
public:
static std::vector<base_pair> code_map;
};
}
namespace parser {
std::vector<base_pair> morse::code_map {{'A', ".-"}, {'B', "-..."}, {'C', "-.-."}, {'D', "-.."},
{'E', "."}, {'F', "..-."}, {'G', "--."}, {'H', "...."},
{'I', ".."}, {'J', ".---"}, {'K', "-.-"}, {'L', ".-.."},
{'M', "--"}, {'N', "-."}, {'O', "---"}, {'P', ".--."},
{'Q', "--.-"}, {'R', ".-."}, {'S', "..."}, {'T', "-"},
{'U', "..-"}, {'V', "...-"}, {'W', ".--"}, {'X', "-..-"},
{'Y', "-.--"}, {'Z', "--.."}};
bool operator==(const base_pair& lhs, base_pair::key_type c)
{
return lhs.p.first == c;
}
bool operator==(base_pair::key_type c, const base_pair& rhs)
{
return (rhs == c);
}
bool operator==(const base_pair& lhs, const base_pair::value_type& str)
{
return lhs.p.second == str;
}
bool operator==(const base_pair::value_type& str, const base_pair& rhs)
{
return (rhs == str);
}
}
namespace parser
{
template<class Algorithm>
class algorithm;
template<>
class algorithm<morse>
{
using value_type = base_pair::value_type;
using key_type = base_pair::key_type;
public:
static value_type from_alpha(base_pair::key_type);
static key_type to_alpha(base_pair::value_type);
};
}
namespace parser
{
algorithm<morse>::value_type algorithm<morse>::from_alpha(algorithm<morse>::key_type key)
{
auto map = morse::code_map;
auto it = std::find(map.begin(), map.end(), std::toupper(key));
if (it != map.end())
return it->get_second();
else throw std::invalid_argument("Could not find key");
}
algorithm<morse>::key_type algorithm<morse>::to_alpha(base_pair::value_type val)
{
auto map = morse::code_map;
auto it = std::find(map.begin(), map.end(), val);
if (it != map.end())
return it->get_first();
else throw std::invalid_argument("Could not find value");
}
}
template<class Morse = parser::algorithm<parser::morse>>
class morse_code_buffer : public std::streambuf
{
public:
typedef Morse parser_type;
morse_code_buffer(const std::string&, std::ios_base::openmode);
int_type overflow(int_type);
int sync();
private:
std::filebuf out;
};
using morse_int_type = morse_code_buffer<>::int_type;
template<>
morse_code_buffer<>::morse_code_buffer(const std::string& path, std::ios_base::openmode mode)
{
out.open(path, mode);
}
template<>
int morse_code_buffer<>::sync() {
return out.pubsync();
}
template<>
morse_int_type morse_code_buffer<>::overflow(morse_int_type c)
{
using Morse = morse_code_buffer<>::parser_type;
if (c == traits_type::eof())
return traits_type::eof();
std::string m;
try {
m = Morse::from_alpha(static_cast<char_type>(c));
} catch(...) {
return traits_type::eof();
}
return out.sputn(m.data(), m.size());
}
struct morse_code_ostream : private morse_code_buffer<>, std::ostream {
morse_code_ostream(std::string const& str)
: morse_code_buffer<>(str, std::ios_base::out)
, std::ostream(this)
{}
};
struct morse_code_istream : private morse_code_buffer<>, std::istream {
morse_code_istream(std::string const& str)
: morse_code_buffer<>(str, std::ios_base::in)
, std::istream(this)
{}
};
int main()
{
morse_code_ostream file("out.txt");
std::ifstream in("out.txt");
std::string s;
in.tie(&file);
file << "ADSHIGFFFS";
in >> s;
std::cout << s;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment