10 #if !defined(GEOGRAPHICLIB_UTILITY_HPP) 11 #define GEOGRAPHICLIB_UTILITY_HPP 1 23 # pragma warning (push) 24 # pragma warning (disable: 4127 4996) 37 static bool gregorian(
int y,
int m,
int d) {
44 return 100 * (100 * y + m) + d >= 17520914;
46 static bool gregorian(
int s) {
60 static int day(
int y,
int m = 1,
int d = 1) {
96 bool greg = gregorian(y, m, d);
97 y += (m + 9) / 12 - 1;
105 + (greg ? (y / 100) / 4 - (y / 100) + 2 : 0)
123 static int day(
int y,
int m,
int d,
bool check) {
124 int s = day(y, m, d);
129 if (!(s > 0 && y == y1 && m == m1 && d == d1))
131 str(y) +
"-" + str(m) +
"-" + str(d)
132 + (s > 0 ?
"; use " +
133 str(y1) +
"-" + str(m1) +
"-" + str(d1) :
134 " before 0001-01-01"));
146 static void date(
int s,
int& y,
int& m,
int& d) {
148 bool greg = gregorian(s);
154 c = (4 * s + 3) / 146097;
155 s -= (c * 146097) / 4;
157 y = (4 * s + 3) / 1461;
160 m = (5 * s + 2) / 153;
161 s -= (153 * m + 2) / 5;
164 m = (m + 2) % 12 + 1;
179 static void date(
const std::string& s,
int& y,
int& m,
int& d) {
181 std::time_t t = std::time(0);
182 struct tm* now = gmtime(&t);
183 y = now->tm_year + 1900;
188 int y1, m1 = 1, d1 = 1;
189 const char* digits =
"0123456789";
190 std::string::size_type p1 = s.find_first_not_of(digits);
191 if (p1 == std::string::npos)
193 else if (s[p1] !=
'-')
198 y1 = val<int>(s.substr(0, p1));
199 if (++p1 == s.size())
201 std::string::size_type p2 = s.find_first_not_of(digits, p1);
202 if (p2 == std::string::npos)
203 m1 = val<int>(s.substr(p1));
204 else if (s[p2] !=
'-')
209 m1 = val<int>(s.substr(p1, p2 - p1));
210 if (++p2 == s.size())
212 d1 = val<int>(s.substr(p2));
215 y = y1; m = m1; d = d1;
227 static int dow(
int y,
int m,
int d) {
return dow(day(y, m, d)); }
257 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 302 using std::floor;
using std::fmod;
307 x = (ix == x && fmod(ix,
Math::real(2)) == 1) ? ix - 1 : ix;
308 s << std::fixed << std::setprecision(1) << x;
309 std::string r(s.str());
311 return r.substr(0, (std::max)(
int(r.size()) - 2, 0));
314 if (p >= 0) s << std::fixed << std::setprecision(p);
315 s << x;
return s.str();
324 static std::string
trim(
const std::string& s) {
327 end = unsigned(s.size());
328 while (beg < end && isspace(s[beg]))
330 while (beg < end && isspace(s[end - 1]))
332 return std::string(s, beg, end-beg);
359 template<
typename T>
static T
val(
const std::string& s) {
363 std::string errmsg, t(trim(s));
365 std::istringstream is(t);
367 errmsg =
"Cannot decode " + t;
370 int pos = int(is.tellg());
371 if (!(pos < 0 || pos ==
int(t.size()))) {
372 errmsg =
"Extra text " + t.substr(pos) +
" at end of " + t;
377 x = std::numeric_limits<T>::is_integer ? 0 : nummatch<T>(t);
387 static T num(const
std::
string& s) {
402 template<
typename T>
static T
nummatch(
const std::string& s) {
406 for (std::string::iterator p = t.begin(); p != t.end(); ++p)
407 *p =
char(std::toupper(*p));
408 for (
size_t i = s.length(); i--;)
409 t[i] =
char(std::toupper(s[i]));
410 int sign = t[0] ==
'-' ? -1 : 1;
411 std::string::size_type p0 = t[0] ==
'-' || t[0] ==
'+' ? 1 : 0;
412 std::string::size_type p1 = t.find_last_not_of(
'0');
413 if (p1 == std::string::npos || p1 + 1 < p0 + 3)
416 t = t.substr(p0, p1 + 1 - p0);
417 if (t ==
"NAN" || t ==
"1.#QNAN" || t ==
"1.#SNAN" || t ==
"1.#IND" ||
419 return Math::NaN<T>();
420 else if (t ==
"INF" || t ==
"1.#INF")
421 return sign * Math::infinity<T>();
440 template<
typename T>
static T
fract(
const std::string& s) {
441 std::string::size_type delim = s.find(
'/');
443 !(delim != std::string::npos && delim >= 1 && delim + 2 <= s.size()) ?
446 val<T>(s.substr(0, delim)) / val<T>(s.substr(delim + 1));
460 static int lookup(
const std::string& s,
char c) {
461 std::string::size_type r = s.find(
char(toupper(c)));
462 return r == std::string::npos ? -1 : int(r);
476 static int lookup(
const char* s,
char c) {
477 const char* p = std::strchr(s, toupper(c));
478 return p != NULL ? int(p - s) : -1;
494 template<
typename ExtT,
typename IntT,
bool bigendp>
495 static void readarray(std::istream& str, IntT array[],
size_t num) {
496 #if GEOGRAPHICLIB_PRECISION < 4 497 if (
sizeof(IntT) ==
sizeof(ExtT) &&
498 std::numeric_limits<IntT>::is_integer ==
499 std::numeric_limits<ExtT>::is_integer)
502 str.read(reinterpret_cast<char*>(array), num *
sizeof(ExtT));
506 for (
size_t i = num; i--;)
507 array[i] = Math::swab<IntT>(array[i]);
513 const int bufsize = 1024;
514 ExtT buffer[bufsize];
518 int n = (std::min)(k, bufsize);
519 str.read(reinterpret_cast<char*>(buffer), n *
sizeof(ExtT));
522 for (
int j = 0; j < n; ++j)
525 Math::swab<ExtT>(buffer[j]));
545 template<
typename ExtT,
typename IntT,
bool bigendp>
546 static void readarray(std::istream& str, std::vector<IntT>& array) {
547 if (array.size() > 0)
548 readarray<ExtT, IntT, bigendp>(str, &array[0], array.size());
563 template<
typename ExtT,
typename IntT,
bool bigendp>
564 static void writearray(std::ostream& str,
const IntT array[],
size_t num)
566 #if GEOGRAPHICLIB_PRECISION < 4 567 if (
sizeof(IntT) ==
sizeof(ExtT) &&
568 std::numeric_limits<IntT>::is_integer ==
569 std::numeric_limits<ExtT>::is_integer &&
573 str.write(reinterpret_cast<const char*>(array), num *
sizeof(ExtT));
580 const int bufsize = 1024;
581 ExtT buffer[bufsize];
585 int n = (std::min)(k, bufsize);
586 for (
int j = 0; j < n; ++j)
589 Math::swab<ExtT>(ExtT(array[i++]));
590 str.write(reinterpret_cast<const char*>(buffer), n *
sizeof(ExtT));
610 template<
typename ExtT,
typename IntT,
bool bigendp>
611 static void writearray(std::ostream& str, std::vector<IntT>& array) {
612 if (array.size() > 0)
613 writearray<ExtT, IntT, bigendp>(str, &array[0], array.size());
631 static bool ParseLine(
const std::string& line,
632 std::string& key, std::string& val);
651 static int set_digits(
int ndigits = 0);
658 template<>
inline std::string Utility::val<std::string>(
const std::string& s)
664 template<>
inline bool Utility::val<bool>(
const std::string& s) {
665 std::string t(trim(s));
666 if (t.empty())
return false;
668 std::istringstream is(t);
670 int pos = int(is.tellg());
671 if (!(pos < 0 || pos ==
int(t.size())))
676 for (std::string::iterator p = t.begin(); p != t.end(); ++p)
677 *p =
char(std::tolower(*p));
680 if (t ==
"f" || t ==
"false")
return false;
683 if (t ==
"n" || t ==
"nil" || t ==
"no")
return false;
686 if (t ==
"off")
return false;
687 else if (t ==
"on")
return true;
690 if (t ==
"t" || t ==
"true")
return true;
693 if (t ==
"y" || t ==
"yes")
return true;
701 #if defined(_MSC_VER) 702 # pragma warning (pop) 705 #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)
static bool isfinite(T x)
Some utility routines for GeographicLib.
static void date(const std::string &s, int &y, int &m, int &d)
static T fractionalyear(const std::string &s)
static std::string trim(const std::string &s)
static void writearray(std::ostream &str, std::vector< IntT > &array)
static int lookup(const char *s, char c)
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
Exception handling for GeographicLib.
Header for GeographicLib::Constants class.
#define GEOGRAPHICLIB_DEPRECATED(msg)
static int lookup(const std::string &s, char c)
static int day(int y, int m=1, int d=1)
static T val(const std::string &s)