ʻOhana
Population structure, admixture history, and selection using learning methods.
Public Types | Public Member Functions
jade::basic_scanner< TChar > Class Template Reference

A template class that parses text and throws meaningful error messages. More...

#include <jade.scanner.hpp>

+ Collaboration diagram for jade::basic_scanner< TChar >:

Public Types

typedef TChar char_type
 The character type. More...
 
typedef std::char_traits< char_typechar_traits_type
 The character traits type. More...
 
typedef std::basic_istream< char_typeistream_type
 The input stream type. More...
 
typedef std::basic_ostream< char_typeostream_type
 The output stream type. More...
 
typedef std::basic_string< char_typestring_type
 The string type. More...
 
typedef std::basic_istringstream< char_typeistringstream_type
 The input stream type. More...
 
typedef std::basic_ostringstream< char_typeostringstream_type
 The output stream type. More...
 

Public Member Functions

 basic_scanner (istream_type &in)
 Initializes a new instance of the class to scan the specified stream. More...
 
 basic_scanner (const string_type &in)
 Initializes a new instance of the class to scan the specified string. More...
 
void expect (const char_type ch)
 Skips whitespace and validates the next symbol in the stream matches the specified character. If the validation fails, this method throws an exception with a meaningful error message. More...
 
bool is_end_of_data () const
 
void read_digits (ostream_type &out)
 Reads a series of digits from the stream and copies them to the specified output stream. This method does not skip whitespace before or after reading the digits. More...
 
double read_double ()
 Skips whitespace and then parses and returns a floating-point value from the specified stream. If there is an error parsing the value, the method throws an exception with a meaningful error message. More...
 
float read_float ()
 Skips whitespace and then parses and returns a floating-point value from the specified stream. If there is an error parsing the value, the method throws an exception with a meaningful error message. More...
 
template<typename TValue >
TValue read_real ()
 Skips whitespace and then parses and returns a floating-point value from the specified stream. If there is an error parsing the value, the method throws an exception with a meaningful error message. More...
 
string_type read_token (char_type const *const delimeters=nullptr)
 Reads and returns a series of characters terminated by the end of the input stream or a specified delimeter. If no delimeters are unspecified, then the method uses whitespace as the delimeters. More...
 
void skip_whitespace ()
 Skips whitespace from the input stream. If the input stream indicates the end of the stream, the method returns without an error. More...
 
bool try_char (const char_type ch)
 Skips whitespace and then checks if the next character from the stream matches the specified character. If it does, the method advances the stream past the character and returns true; otherwise, the method returns false. More...
 

Detailed Description

template<typename TChar>
class jade::basic_scanner< TChar >

A template class that parses text and throws meaningful error messages.

Definition at line 18 of file jade.scanner.hpp.

Member Typedef Documentation

◆ char_traits_type

template<typename TChar >
typedef std::char_traits<char_type> jade::basic_scanner< TChar >::char_traits_type

The character traits type.

Definition at line 25 of file jade.scanner.hpp.

◆ char_type

template<typename TChar >
typedef TChar jade::basic_scanner< TChar >::char_type

The character type.

Definition at line 22 of file jade.scanner.hpp.

◆ istream_type

template<typename TChar >
typedef std::basic_istream<char_type> jade::basic_scanner< TChar >::istream_type

The input stream type.

Definition at line 28 of file jade.scanner.hpp.

◆ istringstream_type

template<typename TChar >
typedef std::basic_istringstream<char_type> jade::basic_scanner< TChar >::istringstream_type

The input stream type.

Definition at line 37 of file jade.scanner.hpp.

◆ ostream_type

template<typename TChar >
typedef std::basic_ostream<char_type> jade::basic_scanner< TChar >::ostream_type

The output stream type.

Definition at line 31 of file jade.scanner.hpp.

◆ ostringstream_type

template<typename TChar >
typedef std::basic_ostringstream<char_type> jade::basic_scanner< TChar >::ostringstream_type

The output stream type.

Definition at line 40 of file jade.scanner.hpp.

◆ string_type

template<typename TChar >
typedef std::basic_string<char_type> jade::basic_scanner< TChar >::string_type

The string type.

Definition at line 34 of file jade.scanner.hpp.

Constructor & Destructor Documentation

◆ basic_scanner() [1/2]

template<typename TChar >
jade::basic_scanner< TChar >::basic_scanner ( istream_type in)
inlineexplicit

Initializes a new instance of the class to scan the specified stream.

Parameters
inThe input stream.

Definition at line 46 of file jade.scanner.hpp.

48  : _ptr ()
49  , _in (in)
50  {
51  }

◆ basic_scanner() [2/2]

template<typename TChar >
jade::basic_scanner< TChar >::basic_scanner ( const string_type in)
inlineexplicit

Initializes a new instance of the class to scan the specified string.

Parameters
inThe input string.

Definition at line 57 of file jade.scanner.hpp.

59  : _ptr (new istringstream_type(in))
60  , _in (*_ptr)
61  {
62  }

Member Function Documentation

◆ expect()

template<typename TChar >
void jade::basic_scanner< TChar >::expect ( const char_type  ch)
inline

Skips whitespace and validates the next symbol in the stream matches the specified character. If the validation fails, this method throws an exception with a meaningful error message.

Exceptions
jade::errorThrown if the stream provides an unexpected symbol.
Parameters
chThe expected character.

Definition at line 72 of file jade.scanner.hpp.

74  {
75  //
76  // Skip whitespace before validating the character.
77  //
79 
80  //
81  // Throw an excepiton if encountering the end of the stream.
82  //
83  const auto actual = _in.peek();
84  if (actual < 0)
85  throw error()
86  << "expected symbol '" << char_type(ch) << "' "
87  << "but encountered end of stream";
88 
89  //
90  // Validate the symbol matches the expected value.
91  //
92  if (actual == ch)
93  {
94  _in.get();
95  return;
96  }
97 
98  if (::isprint(ch))
99  throw error()
100  << "expected symbol '" << char_type(ch) << "' "
101  << "but encountered symbol '"
102  << char_type(actual) << "'";
103 
104  throw error()
105  << "expected symbol '" << char_type(ch) << "' "
106  << "but encountered ASCII code " << actual;
107  }
+ Here is the call graph for this function:

◆ is_end_of_data()

template<typename TChar >
bool jade::basic_scanner< TChar >::is_end_of_data ( ) const
inline
Returns
True if all data has been read from the scanner.

Definition at line 112 of file jade.scanner.hpp.

113  {
114  return _in.peek() < 0;
115  }

◆ read_digits()

template<typename TChar >
void jade::basic_scanner< TChar >::read_digits ( ostream_type out)
inline

Reads a series of digits from the stream and copies them to the specified output stream. This method does not skip whitespace before or after reading the digits.

Parameters
outThe output stream.

Definition at line 122 of file jade.scanner.hpp.

124  {
125  while (::isdigit(_in.peek()))
126  out << char_type(_in.get());
127  }
+ Here is the caller graph for this function:

◆ read_double()

template<typename TChar >
double jade::basic_scanner< TChar >::read_double ( )
inline

Skips whitespace and then parses and returns a floating-point value from the specified stream. If there is an error parsing the value, the method throws an exception with a meaningful error message.

Returns
A floating-point value.
Exceptions
jade::errorThrown if there is an error parsing the length.

Definition at line 139 of file jade.scanner.hpp.

140  {
141  return read_real<double>();
142  }

◆ read_float()

template<typename TChar >
float jade::basic_scanner< TChar >::read_float ( )
inline

Skips whitespace and then parses and returns a floating-point value from the specified stream. If there is an error parsing the value, the method throws an exception with a meaningful error message.

Returns
A floating-point value.
Exceptions
jade::errorThrown if there is an error parsing the length.

Definition at line 154 of file jade.scanner.hpp.

155  {
156  return read_real<float>();
157  }

◆ read_real()

template<typename TChar >
template<typename TValue >
TValue jade::basic_scanner< TChar >::read_real ( )
inline

Skips whitespace and then parses and returns a floating-point value from the specified stream. If there is an error parsing the value, the method throws an exception with a meaningful error message.

Returns
A floating-point value.
Exceptions
jade::errorThrown if there is an error parsing the length.

Definition at line 170 of file jade.scanner.hpp.

171  {
172  static const auto hyphen = char_type('-');
173  static const auto period = char_type('.');
174 
175  //
176  // Initially skip whitespace.
177  //
178  skip_whitespace();
179 
180  ostringstream_type out;
181 
182  //
183  // Check for negative values.
184  //
185  if (try_char(hyphen))
186  out << hyphen;
187 
188  //
189  // Read values before the decimal place.
190  //
191  read_digits(out);
192 
193  //
194  // Check for a decimal, possibly reading additional digits.
195  //
196  if (try_char(period))
197  {
198  out << period;
199  read_digits(out);
200  }
201 
202  //
203  // If no symbols exist in the output buffer, this is invalid.
204  //
205  const auto length_str = out.str();
206  if (length_str.empty())
207  throw error(
208  "expected a floating-point value but "
209  "did not encounter any digits");
210 
211  //
212  // Parse and return the digits as a floating-point value, throwing
213  // an exception in the case of an error.
214  //
215  istringstream_type length_in (length_str);
216  TValue length;
217  if (length_in >> length)
218  return length;
219  throw error()
220  << "expected a length but encountered '"
221  << length_str << "'";
222  }
+ Here is the call graph for this function:

◆ read_token()

template<typename TChar >
string_type jade::basic_scanner< TChar >::read_token ( char_type const *const  delimeters = nullptr)
inline

Reads and returns a series of characters terminated by the end of the input stream or a specified delimeter. If no delimeters are unspecified, then the method uses whitespace as the delimeters.

Parameters
delimetersThe delimeters, or nullptr.
Returns
The token.

Definition at line 232 of file jade.scanner.hpp.

233  {
234  static const char_type fallback[] =
235  {
236  char_type(' '),
237  char_type('\n'),
238  char_type('\t'),
239  char_type('\0')
240  };
241 
242  //
243  // Use whitespace as the delimeters unless specified otherwise.
244  //
245  const auto delims = delimeters == nullptr ? fallback : delimeters;
246  const auto length = char_traits_type::length(delims);
247 
248  ostringstream_type out;
249 
250  for (;;)
251  {
252  auto ch = _in.peek();
253 
254  if (ch < 0 || nullptr != char_traits_type::find(
255  delims, length, char_type(ch)))
256  return out.str();
257 
258  out << char_type(_in.get());
259  }
260  }

◆ skip_whitespace()

template<typename TChar >
void jade::basic_scanner< TChar >::skip_whitespace ( )
inline

Skips whitespace from the input stream. If the input stream indicates the end of the stream, the method returns without an error.

Definition at line 267 of file jade.scanner.hpp.

268  {
269  while (::isspace(_in.peek()))
270  _in.get();
271  }
+ Here is the caller graph for this function:

◆ try_char()

template<typename TChar >
bool jade::basic_scanner< TChar >::try_char ( const char_type  ch)
inline

Skips whitespace and then checks if the next character from the stream matches the specified character. If it does, the method advances the stream past the character and returns true; otherwise, the method returns false.

Returns
True if encountering the character; otherwise, false.
Parameters
chThe character to test.

Definition at line 281 of file jade.scanner.hpp.

283  {
284  //
285  // Skip whitespace before testing the next symbol.
286  //
287  skip_whitespace();
288 
289  //
290  // Return false if the symbol does not match or if there are no more
291  // symbols available in the input stream.
292  //
293  if (ch != _in.peek())
294  return false;
295 
296  //
297  // Advance past the character and return true to indicate a match.
298  //
299  _in.get();
300  return true;
301  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

The documentation for this class was generated from the following file:
jade::basic_scanner::istringstream_type
std::basic_istringstream< char_type > istringstream_type
The input stream type.
Definition: jade.scanner.hpp:37
jade::basic_scanner::char_type
TChar char_type
The character type.
Definition: jade.scanner.hpp:22
jade::basic_scanner::read_digits
void read_digits(ostream_type &out)
Reads a series of digits from the stream and copies them to the specified output stream....
Definition: jade.scanner.hpp:122
jade::basic_scanner::ostringstream_type
std::basic_ostringstream< char_type > ostringstream_type
The output stream type.
Definition: jade.scanner.hpp:40
jade::basic_scanner::skip_whitespace
void skip_whitespace()
Skips whitespace from the input stream. If the input stream indicates the end of the stream,...
Definition: jade.scanner.hpp:267
jade::basic_scanner::try_char
bool try_char(const char_type ch)
Skips whitespace and then checks if the next character from the stream matches the specified characte...
Definition: jade.scanner.hpp:281