Created
November 6, 2014 18:56
-
-
Save dgodfrey206/4481728f43eedcc29479 to your computer and use it in GitHub Desktop.
Employee class with I/O
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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