1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
|
#include <ciso646>
#include <sstream>
#include <stdexcept>
#include <string>
//----------------------------------------------------------------------------
// string_to <T> ()
//----------------------------------------------------------------------------
// Convert the argument string to a typed object.
// Uses the standard streams functionality.
// (So the object type must have an extraction operator.)
//
// bool string_to( s, &result )
// Attempts conversion. Returns true on success, false otherwise.
//
// result string_to <T> ( s )
// Attempts conversion. Returns result on success.
// Throws std::invalid_argument on failure.
//
template <typename T, typename CharT = char, typename Allocator = std::allocator <CharT> >
bool string_to( const std::basic_string <CharT, Allocator> & s, T& result )
{
// Convert string argument to T
std::basic_istringstream <CharT> ss( s );
ss >> result >> std::ws;
// Stream should be in good standing with nothing left over
return ss.eof();
}
template <typename T, typename CharT = char, typename Allocator = std::allocator <CharT> >
T string_to( const std::basic_string <CharT, Allocator> & s )
{
T result;
if (!string_to( s, result ))
throw std::invalid_argument( "T string_to <T, CharT, Allocator> ()" );
return result;
}
template <typename T>
bool string_to( const std::string& s, T& result )
{
return string_to <T, char> ( s, result );
}
template <typename T>
T string_to( const std::string& s )
{
return string_to <T, char> ( s );
}
//----------------------------------------------------------------------------
// istream& getline( istream&, &result [,delim] )
//----------------------------------------------------------------------------
// Extract a typed thing (not necessarily a string) from a stream.
//
// On success, the input stream is in a good state and result contains the
// converted value.
//
// On failure, the input stream will be in the fail state and the result
// contains a default-constructed value. (As per the C++11 standard's
// stupid mandate.)
//
template <typename T, typename CharT>
std::basic_istream <CharT> &
getline( std::basic_istream <CharT> & ins, T& result, CharT delim )
{
std::basic_string <CharT> s;
if (!std::getline( ins, s, delim ) or !string_to <T> ( s, result ))
{
result = T();
ins.setstate( std::ios::failbit );
}
return ins;
}
template <typename T, typename CharT>
std::basic_istream <CharT> &
getline( std::basic_istream <CharT> & ins, T& result )
{
std::basic_string <CharT> s;
if (!std::getline( ins, s ) or !string_to <T> ( s, result ))
{
result = T();
ins.setstate( std::ios::failbit );
}
return ins;
}
|