Skip to content

Instantly share code, notes, and snippets.

@dgodfrey206
Created November 6, 2014 18:56
Show Gist options
  • Save dgodfrey206/4481728f43eedcc29479 to your computer and use it in GitHub Desktop.
Save dgodfrey206/4481728f43eedcc29479 to your computer and use it in GitHub Desktop.
Employee class with I/O
#include <iostream>
#include <sstream>
#include <string>
#include <boost/io/ios_state.hpp>
template <class cT>
class whitespace_fmt;
template <>
class whitespace_fmt<char> : public std::ctype<char>
{
private:
mask table[table_size];
public:
explicit whitespace_fmt(std::size_t refs = 0)
: std::ctype<char>(table, false, refs)
{
std::copy(classic_table(), classic_table() + table_size, table);
table[','] = static_cast<mask>(space | print);
}
};
template <>
class whitespace_fmt<wchar_t> : public std::ctype<wchar_t>
{
public:
explicit whitespace_fmt(std::size_t refs = 0)
: std::ctype<wchar_t>(refs)
{ }
bool do_is(mask m, char_type c) const
{
return ((m & space) && c == L',') || ctype::do_is(m, c);
}
};
class Person
{
friend class Person_fmt;
private:
std::string firstname, lastname;
int month, day, year;
};
class Person_fmt : public std::locale::facet
{
public:
template <class cT, class traits>
friend std::basic_ostream<cT, traits>& operator<<(std::basic_ostream<cT, traits>&, Person const&);
template <class cT, class traits>
friend std::basic_istream<cT, traits>& operator>>(std::basic_istream<cT, traits>&, Person&);
static std::locale::id id;
explicit Person_fmt(std::size_t refs = 0);
protected:
template <class cT, class traits>
void get(std::basic_istream<cT, traits>&, Person&) const;
template <class cT, class traits>
void put(std::basic_ostream<cT, traits>&, Person const&) const;
};
std::locale::id Person_fmt::id;
Person_fmt::Person_fmt(std::size_t refs)
: std::locale::facet(refs)
{ }
/*
template <class cT, class traits>
struct state_saver
{
using ios_type = std::basic_ios<cT, traits>;
public:
state_saver(ios_type& from, ios_type& to) : m_from(from), m_to(to) { to.rdbuf(from.rdbuf()); to.copyfmt(from); }
~state_saver() { m_to.clear(m_from.rdstate()); m_to.rdbuf(m_from.rdbuf()); }
private:
ios_type& m_from;
ios_type& m_to;
};
*/
template <class cT, class traits>
void Person_fmt::get(std::basic_istream<cT, traits>& is, Person& p) const
{
boost::io::ios_all_saver saver(is);
if (is)
{
is.imbue(std::locale(is.getloc(), new whitespace_fmt<cT>));
is >> p.lastname >> p.firstname >> p.month >> p.day >> p.year;
}
}
template <class cT, class traits>
void Person_fmt::put(std::basic_ostream<cT, traits>& os, Person const& p) const
{
os << "Name: " << p.firstname << ", " << p.lastname << '\n';
os << "DOB: " << p.month << "-" << p.day << "-" << p.year << '\n';
}
template <class cT, class traits>
std::basic_ostream<cT, traits>& operator<<(std::basic_ostream<cT, traits>& os, Person const& p)
{
if (std::has_facet<Person_fmt>(os.getloc()))
std::use_facet<Person_fmt>(os.getloc()).put(os, p);
return os;
}
template <class cT, class traits>
std::basic_istream<cT, traits>& operator>>(std::basic_istream<cT, traits>& is, Person& p)
{
if (std::has_facet<Person_fmt>(is.getloc()))
std::use_facet<Person_fmt>(is.getloc()).get(is, p);
return is;
}
int main()
{
std::stringstream stream("doe,john,12,5,97");
stream.imbue(std::locale(stream.getloc(), new Person_fmt));
std::cout.imbue(std::locale(std::cout.getloc(), new Person_fmt));
Person p;
if (stream >> p)
std::cout << p;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment