forked from lijiext/lammps
Add ValueTokenizer
This commit is contained in:
parent
46239e4577
commit
7ac0f869ef
|
@ -16,6 +16,7 @@
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
#include "tokenizer.h"
|
#include "tokenizer.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
using namespace LAMMPS_NS;
|
using namespace LAMMPS_NS;
|
||||||
|
|
||||||
|
@ -44,6 +45,14 @@ Tokenizer::iterator Tokenizer::end() {
|
||||||
return tokens.end();
|
return tokens.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tokenizer::const_iterator Tokenizer::cbegin() const {
|
||||||
|
return tokens.cbegin();
|
||||||
|
}
|
||||||
|
|
||||||
|
Tokenizer::const_iterator Tokenizer::cend() const {
|
||||||
|
return tokens.cend();
|
||||||
|
}
|
||||||
|
|
||||||
const std::string & Tokenizer::operator[](size_t index) {
|
const std::string & Tokenizer::operator[](size_t index) {
|
||||||
return tokens[index];
|
return tokens[index];
|
||||||
}
|
}
|
||||||
|
@ -51,3 +60,74 @@ const std::string & Tokenizer::operator[](size_t index) {
|
||||||
const size_t Tokenizer::count() const {
|
const size_t Tokenizer::count() const {
|
||||||
return tokens.size();
|
return tokens.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ValueTokenizer::ValueTokenizer(const std::string & str, const std::string & seperators) : tokens(str, seperators) {
|
||||||
|
current = tokens.begin();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ValueTokenizer::has_next() const {
|
||||||
|
return current != tokens.cend();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ValueTokenizer::next_string() {
|
||||||
|
if (has_next()) {
|
||||||
|
std::string value = *current;
|
||||||
|
++current;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
int ValueTokenizer::next_int() {
|
||||||
|
if (has_next()) {
|
||||||
|
if(!utils::is_integer(*current)) {
|
||||||
|
throw InvalidIntegerException(*current);
|
||||||
|
}
|
||||||
|
int value = atoi(current->c_str());
|
||||||
|
++current;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bigint ValueTokenizer::next_bigint() {
|
||||||
|
if (has_next()) {
|
||||||
|
if(!utils::is_integer(*current)) {
|
||||||
|
throw InvalidIntegerException(*current);
|
||||||
|
}
|
||||||
|
bigint value = ATOBIGINT(current->c_str());
|
||||||
|
++current;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
tagint ValueTokenizer::next_tagint() {
|
||||||
|
if (current != tokens.end()) {
|
||||||
|
if(!utils::is_integer(*current)) {
|
||||||
|
throw InvalidIntegerException(*current);
|
||||||
|
}
|
||||||
|
tagint value = ATOTAGINT(current->c_str());
|
||||||
|
++current;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double ValueTokenizer::next_double() {
|
||||||
|
if (current != tokens.end()) {
|
||||||
|
if(!utils::is_double(*current)) {
|
||||||
|
throw InvalidFloatException(*current);
|
||||||
|
}
|
||||||
|
|
||||||
|
double value = atof(current->c_str());
|
||||||
|
++current;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ValueTokenizer::skip(int ntokens) {
|
||||||
|
current = std::next(current, ntokens);
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "lmptype.h"
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
namespace LAMMPS_NS {
|
namespace LAMMPS_NS {
|
||||||
|
|
||||||
|
@ -27,16 +29,62 @@ class Tokenizer {
|
||||||
std::vector<std::string> tokens;
|
std::vector<std::string> tokens;
|
||||||
public:
|
public:
|
||||||
typedef std::vector<std::string>::iterator iterator;
|
typedef std::vector<std::string>::iterator iterator;
|
||||||
|
typedef std::vector<std::string>::const_iterator const_iterator;
|
||||||
|
|
||||||
Tokenizer(const std::string & str, const std::string & seperators = " \t\r\n\f");
|
Tokenizer(const std::string & str, const std::string & seperators = " \t\r\n\f");
|
||||||
|
|
||||||
iterator begin();
|
iterator begin();
|
||||||
iterator end();
|
iterator end();
|
||||||
|
const_iterator cbegin() const;
|
||||||
|
const_iterator cend() const;
|
||||||
|
|
||||||
const std::string & operator[](size_t index);
|
const std::string & operator[](size_t index);
|
||||||
const size_t count() const;
|
const size_t count() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class TokenizerException : public std::exception {
|
||||||
|
std::string message;
|
||||||
|
public:
|
||||||
|
TokenizerException(const std::string & msg, const std::string & token) : message(msg + ": '" + token + "'") {
|
||||||
|
}
|
||||||
|
|
||||||
|
~TokenizerException() throw() {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const char * what() const throw() {
|
||||||
|
return message.c_str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InvalidIntegerException : public TokenizerException {
|
||||||
|
public:
|
||||||
|
InvalidIntegerException(const std::string & token) : TokenizerException("Not a valid integer number", token) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class InvalidFloatException : public TokenizerException {
|
||||||
|
public:
|
||||||
|
InvalidFloatException(const std::string & token) : TokenizerException("Not a valid floating-point number", token) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class ValueTokenizer {
|
||||||
|
Tokenizer tokens;
|
||||||
|
Tokenizer::const_iterator current;
|
||||||
|
public:
|
||||||
|
ValueTokenizer(const std::string & str, const std::string & seperators = " \t\r\n\f");
|
||||||
|
|
||||||
|
std::string next_string();
|
||||||
|
tagint next_tagint();
|
||||||
|
bigint next_bigint();
|
||||||
|
int next_int();
|
||||||
|
double next_double();
|
||||||
|
|
||||||
|
bool has_next() const;
|
||||||
|
void skip(int ntokens);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -59,3 +59,43 @@ TEST(Tokenizer, for_loop) {
|
||||||
ASSERT_THAT(list[0], Eq("test"));
|
ASSERT_THAT(list[0], Eq("test"));
|
||||||
ASSERT_THAT(list[1], Eq("word"));
|
ASSERT_THAT(list[1], Eq("word"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(ValueTokenizer, empty_string) {
|
||||||
|
ValueTokenizer values("");
|
||||||
|
ASSERT_FALSE(values.has_next());
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ValueTokenizer, bad_integer) {
|
||||||
|
ValueTokenizer values("f10");
|
||||||
|
ASSERT_THROW(values.next_int(), InvalidIntegerException);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ValueTokenizer, bad_double) {
|
||||||
|
ValueTokenizer values("1a.0");
|
||||||
|
ASSERT_THROW(values.next_double(), InvalidFloatException);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ValueTokenizer, valid_int) {
|
||||||
|
ValueTokenizer values("10");
|
||||||
|
ASSERT_EQ(values.next_int(), 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ValueTokenizer, valid_tagint) {
|
||||||
|
ValueTokenizer values("42");
|
||||||
|
ASSERT_EQ(values.next_tagint(), 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ValueTokenizer, valid_bigint) {
|
||||||
|
ValueTokenizer values("42");
|
||||||
|
ASSERT_EQ(values.next_bigint(), 42);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ValueTokenizer, valid_double) {
|
||||||
|
ValueTokenizer values("3.14");
|
||||||
|
ASSERT_DOUBLE_EQ(values.next_double(), 3.14);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(ValueTokenizer, valid_double_with_exponential) {
|
||||||
|
ValueTokenizer values("3.14e22");
|
||||||
|
ASSERT_DOUBLE_EQ(values.next_double(), 3.14e22);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue