Gemmi C++ API
Loading...
Searching...
No Matches
atox.hpp
Go to the documentation of this file.
1// Copyright 2018 Global Phasing Ltd.
2//
3// Locale-independent functions that convert string to integer,
4// equivalents of standard isspace and isdigit, and a few helper functions.
5//
6// This file is named similarly to the standard functions atoi() and atof().
7// But the functions here are not meant to be equivalent to the standard
8// library functions. They are locale-independent (a good thing when reading
9// numbers from files). They don't set errno, don't signal overflow and
10// underflow. Due to the limited scope these functions tend to be faster
11// than the standard-library ones.
12
13#ifndef GEMMI_ATOX_HPP_
14#define GEMMI_ATOX_HPP_
15
16#include <cstdint>
17#include <stdexcept> // for invalid_argument
18#include <string>
19
20namespace gemmi {
21
22// equivalent of std::isspace for C locale (no handling of EOF)
23inline bool is_space(char c) {
24 static const std::uint8_t table[256] = { // 1 for 9-13 and 32
25 0,0,0,0,0,0,0,0, 0,1,1,1,1,1,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
26 1,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
27 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
28 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
29 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
30 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
31 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,
32 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0
33 };
34 return table[(std::uint8_t)c] != 0;
35}
36
37// equivalent of std::isblank for C locale (no handling of EOF)
38inline bool is_blank(char c) {
39 return c == ' ' || c == '\t';
40}
41
42// equivalent of std::isdigit for C locale (no handling of EOF)
43inline bool is_digit(char c) {
44 return c >= '0' && c <= '9';
45}
46
47inline const char* skip_blank(const char* p) {
48 if (p)
49 while (is_blank(*p))
50 ++p;
51 return p;
52}
53
54inline const char* skip_word(const char* p) {
55 if (p)
56 while (*p != '\0' && !is_space(*p))
57 ++p;
58 return p;
59}
60
61inline std::string read_word(const char* line) {
63 return std::string(line, skip_word(line));
64}
65
66inline std::string read_word(const char* line, const char** endptr) {
69 return std::string(line, *endptr);
70}
71
72// no checking for overflow
73inline int string_to_int(const char* p, bool checked, size_t length=0) {
74 int mult = -1;
75 int n = 0;
76 size_t i = 0;
77 while ((length == 0 || i < length) && is_space(p[i]))
78 ++i;
79 if (p[i] == '-') {
80 mult = 1;
81 ++i;
82 } else if (p[i] == '+') {
83 ++i;
84 }
85 bool has_digits = false;
86 // use negative numbers because INT_MIN < -INT_MAX
87 for (; (length == 0 || i < length) && is_digit(p[i]); ++i) {
88 n = n * 10 - (p[i] - '0');
89 has_digits = true;
90 }
91 if (checked) {
92 while ((length == 0 || i < length) && is_space(p[i]))
93 ++i;
94 if (!has_digits || p[i] != '\0')
95 throw std::invalid_argument("not an integer: " +
96 std::string(p, length ? length : i+1));
97 }
98 return mult * n;
99}
100
101inline int string_to_int(const std::string& str, bool checked) {
102 return string_to_int(str.c_str(), checked);
103}
104
105inline int simple_atoi(const char* p, const char** endptr=nullptr) {
106 int mult = -1;
107 int n = 0;
108 while (is_space(*p))
109 ++p;
110 if (*p == '-') {
111 mult = 1;
112 ++p;
113 } else if (*p == '+') {
114 ++p;
115 }
116 for (; is_digit(*p); ++p)
117 n = n * 10 - (*p - '0'); // use negative numbers because INT_MIN < -INT_MAX
118 if (endptr)
119 *endptr = p;
120 return mult * n;
121}
122
123inline int no_sign_atoi(const char* p, const char** endptr=nullptr) {
124 int n = 0;
125 while (is_space(*p))
126 ++p;
127 for (; is_digit(*p); ++p)
128 n = n * 10 + (*p - '0');
129 if (endptr)
130 *endptr = p;
131 return n;
132}
133
134} // namespace gemmi
135#endif
int string_to_int(const char *p, bool checked, size_t length=0)
Definition atox.hpp:73
int simple_atoi(const char *p, const char **endptr=nullptr)
Definition atox.hpp:105
std::string read_word(const char *line)
Definition atox.hpp:61
bool is_digit(char c)
Definition atox.hpp:43
bool is_blank(char c)
Definition atox.hpp:38
const char * skip_word(const char *p)
Definition atox.hpp:54
bool is_space(char c)
Definition atox.hpp:23
const char * skip_blank(const char *p)
Definition atox.hpp:47
int no_sign_atoi(const char *p, const char **endptr=nullptr)
Definition atox.hpp:123