Gemmi C++ API
Loading...
Searching...
No Matches
numb.hpp
Go to the documentation of this file.
1// Copyright 2017 Global Phasing Ltd.
2//
3// Utilities for parsing CIF numbers (the CIF spec calls it 'numb').
4//
5// Numb - the numeric type in CIF - is a number with optional
6// standard uncertainty (s.u.) in brackets: 1.23(8).
7// Mmcif file do not use s.u. though - they define own numeric categories.
8
9#ifndef GEMMI_NUMB_HPP_
10#define GEMMI_NUMB_HPP_
11
12#include <cmath> // for NAN
13#include <string>
14#include "third_party/fast_float.h"
15
16namespace gemmi {
17namespace cif {
18
19inline double as_number(const std::string& s, double nan=NAN) {
20 const char* start = s.data();
21 const char* end = s.data() + s.size();
22 if (*start == '+')
23 ++start;
24 // NaN, Inf and -Inf are not allowed in CIF
25 char f = start[int(*start == '-')] | 0x20;
26 if (f == 'i' || f == 'n')
27 return nan;
28
29 double d;
30 auto result = fast_float::from_chars(start, end, d);
31 if (result.ec != std::errc())
32 return nan;
33 if (*result.ptr == '(') {
34 const char* p = result.ptr + 1;
35 while (*p >= '0' && *p <= '9')
36 ++p;
37 if (*p == ')')
38 result.ptr = p + 1;
39 }
40 return result.ptr == end ? d : nan;
41}
42
43inline bool is_numb(const std::string& s) {
44 return !std::isnan(as_number(s));
45}
46
47
48// for use in templates (see also as_any() functions in cifdoc.hpp)
49inline float as_any(const std::string& s, float null) {
50 return (float) as_number(s, null);
51}
52inline double as_any(const std::string& s, double null) {
53 return as_number(s, null);
54}
55
56} // namespace cif
57} // namespace gemmi
58#endif
int as_any(const std::string &s, int null)
Definition cifdoc.hpp:117
double as_number(const std::string &s, double nan=NAN)
Definition numb.hpp:19
bool is_numb(const std::string &s)
Definition numb.hpp:43