10 #if !defined(GEOGRAPHICLIB_UTILITY_HPP) 11 #define GEOGRAPHICLIB_UTILITY_HPP 1 22 # pragma warning (push) 23 # pragma warning (disable: 4127 4996) 36 static bool gregorian(
int y,
int m,
int d) {
43 return 100 * (100 * y + m) + d >= 17520914;
45 static bool gregorian(
int s) {
59 static int day(
int y,
int m = 1,
int d = 1) {
95 bool greg = gregorian(y, m, d);
96 y += (m + 9) / 12 - 1;
104 + (greg ? (y / 100) / 4 - (y / 100) + 2 : 0)
122 static int day(
int y,
int m,
int d,
bool check) {
123 int s = day(y, m, d);
128 if (!(s > 0 && y == y1 && m == m1 && d == d1))
130 str(y) +
"-" + str(m) +
"-" + str(d)
131 + (s > 0 ?
"; use " +
132 str(y1) +
"-" + str(m1) +
"-" + str(d1) :
133 " before 0001-01-01"));
145 static void date(
int s,
int& y,
int& m,
int& d) {
147 bool greg = gregorian(s);
153 c = (4 * s + 3) / 146097;
154 s -= (c * 146097) / 4;
156 y = (4 * s + 3) / 1461;
159 m = (5 * s + 2) / 153;
160 s -= (153 * m + 2) / 5;
163 m = (m + 2) % 12 + 1;
178 static void date(
const std::string& s,
int& y,
int& m,
int& d) {
180 std::time_t t = std::time(0);
181 struct tm* now = gmtime(&t);
182 y = now->tm_year + 1900;
187 int y1, m1 = 1, d1 = 1;
188 const char* digits =
"0123456789";
189 std::string::size_type p1 = s.find_first_not_of(digits);
190 if (p1 == std::string::npos)
192 else if (s[p1] !=
'-')
197 y1 = num<int>(s.substr(0, p1));
198 if (++p1 == s.size())
200 std::string::size_type p2 = s.find_first_not_of(digits, p1);
201 if (p2 == std::string::npos)
202 m1 = num<int>(s.substr(p1));
203 else if (s[p2] !=
'-')
208 m1 = num<int>(s.substr(p1, p2 - p1));
209 if (++p2 == s.size())
211 d1 = num<int>(s.substr(p2));
214 y = y1; m = m1; d = d1;
226 static int dow(
int y,
int m,
int d) {
return dow(day(y, m, d)); }
256 catch (
const std::exception&) {
260 int t = day(y, m, d,
true);
261 return T(y) + T(t - day(y)) / T(day(y + 1) - day(y));
276 template<
typename T>
static std::string
str(T x,
int p = -1) {
277 std::ostringstream s;
278 if (p >= 0) s << std::fixed << std::setprecision(p);
279 s << x;
return s.str();
296 return x < 0 ? std::string(
"-inf") :
297 (x > 0 ? std::string(
"inf") : std::string(
"nan"));
298 std::ostringstream s;
299 #if GEOGRAPHICLIB_PRECISION == 4 304 long long ix = (
long long)(floor(x +
Math::real(0.5)));
312 if (p >= 0) s << std::fixed << std::setprecision(p);
313 s << x;
return s.str();
324 template<
typename T>
static T
num(
const std::string& s) {
328 std::istringstream is(s);
330 errmsg =
"Cannot decode " + s;
333 int pos = int(is.tellg());
334 if (!(pos < 0 || pos ==
int(s.size()))) {
335 errmsg =
"Extra text " + s.substr(pos) +
" at end of " + s;
340 x = std::numeric_limits<T>::is_integer ? 0 : nummatch<T>(s);
354 template<
typename T>
static T
nummatch(
const std::string& s) {
358 t.resize(s.length());
359 std::transform(s.begin(), s.end(), t.begin(), (int(*)(int))std::toupper);
360 for (
size_t i = s.length(); i--;)
361 t[i] =
char(std::toupper(s[i]));
362 int sign = t[0] ==
'-' ? -1 : 1;
363 std::string::size_type p0 = t[0] ==
'-' || t[0] ==
'+' ? 1 : 0;
364 std::string::size_type p1 = t.find_last_not_of(
'0');
365 if (p1 == std::string::npos || p1 + 1 < p0 + 3)
368 t = t.substr(p0, p1 + 1 - p0);
369 if (t ==
"NAN" || t ==
"1.#QNAN" || t ==
"1.#SNAN" || t ==
"1.#IND" ||
371 return Math::NaN<T>();
372 else if (t ==
"INF" || t ==
"1.#INF")
373 return sign * Math::infinity<T>();
385 template<
typename T>
static T
fract(
const std::string& s) {
386 std::string::size_type delim = s.find(
'/');
388 !(delim != std::string::npos && delim >= 1 && delim + 2 <= s.size()) ?
391 num<T>(s.substr(0, delim)) / num<T>(s.substr(delim + 1));
405 static int lookup(
const std::string& s,
char c) {
406 std::string::size_type r = s.find(
char(toupper(c)));
407 return r == std::string::npos ? -1 : int(r);
423 template<
typename ExtT,
typename IntT,
bool bigendp>
425 IntT array[],
size_t num) {
426 #if GEOGRAPHICLIB_PRECISION < 4 427 if (
sizeof(IntT) ==
sizeof(ExtT) &&
428 std::numeric_limits<IntT>::is_integer ==
429 std::numeric_limits<ExtT>::is_integer)
432 str.read(reinterpret_cast<char*>(array), num *
sizeof(ExtT));
436 for (
size_t i = num; i--;)
437 array[i] = Math::swab<IntT>(array[i]);
443 const int bufsize = 1024;
444 ExtT buffer[bufsize];
448 int n = (std::min)(k, bufsize);
449 str.read(reinterpret_cast<char*>(buffer), n *
sizeof(ExtT));
452 for (
int j = 0; j < n; ++j)
455 Math::swab<ExtT>(buffer[j]));
475 template<
typename ExtT,
typename IntT,
bool bigendp>
477 std::vector<IntT>& array) {
478 if (array.size() > 0)
479 readarray<ExtT, IntT, bigendp>(str, &array[0], array.size());
494 template<
typename ExtT,
typename IntT,
bool bigendp>
496 const IntT array[],
size_t num) {
497 #if GEOGRAPHICLIB_PRECISION < 4 498 if (
sizeof(IntT) ==
sizeof(ExtT) &&
499 std::numeric_limits<IntT>::is_integer ==
500 std::numeric_limits<ExtT>::is_integer &&
504 str.write(reinterpret_cast<const char*>(array), num *
sizeof(ExtT));
511 const int bufsize = 1024;
512 ExtT buffer[bufsize];
516 int n = (std::min)(k, bufsize);
517 for (
int j = 0; j < n; ++j)
520 Math::swab<ExtT>(ExtT(array[i++]));
521 str.write(reinterpret_cast<const char*>(buffer), n *
sizeof(ExtT));
541 template<
typename ExtT,
typename IntT,
bool bigendp>
543 std::vector<IntT>& array) {
544 if (array.size() > 0)
545 writearray<ExtT, IntT, bigendp>(str, &array[0], array.size());
563 static bool ParseLine(
const std::string& line,
564 std::string& key, std::string& val);
577 static int set_digits(
int ndigits = 0);
583 #if defined(_MSC_VER) 584 # pragma warning (pop) 587 #endif // GEOGRAPHICLIB_UTILITY_HPP static T fract(const std::string &s)
static int day(int y, int m, int d, bool check)
#define GEOGRAPHICLIB_EXPORT
static void readarray(std::istream &str, std::vector< IntT > &array)
static void readarray(std::istream &str, IntT array[], size_t num)
Some utility routines for GeographicLib.
static void date(const std::string &s, int &y, int &m, int &d)
static bool isfinite(T x)
static T fractionalyear(const std::string &s)
static void writearray(std::ostream &str, std::vector< IntT > &array)
static T nummatch(const std::string &s)
static void writearray(std::ostream &str, const IntT array[], size_t num)
static std::string str(Math::real x, int p=-1)
static void date(int s, int &y, int &m, int &d)
Namespace for GeographicLib.
static std::string str(T x, int p=-1)
static int dow(int y, int m, int d)
static const bool bigendian
static T num(const std::string &s)
Exception handling for GeographicLib.
Header for GeographicLib::Constants class.
static int lookup(const std::string &s, char c)
static int day(int y, int m=1, int d=1)