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 = val<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 = val<int>(s.substr(p1));
203 else if (s[p2] !=
'-')
208 m1 = val<int>(s.substr(p1, p2 - p1));
209 if (++p2 == s.size())
211 d1 = val<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&) {}
259 int t = day(y, m, d,
true);
260 return T(y) + T(t - day(y)) / T(day(y + 1) - day(y));
275 template<
typename T>
static std::string
str(T x,
int p = -1) {
276 std::ostringstream s;
277 if (p >= 0) s << std::fixed << std::setprecision(p);
278 s << x;
return s.str();
295 return x < 0 ? std::string(
"-inf") :
296 (x > 0 ? std::string(
"inf") : std::string(
"nan"));
297 std::ostringstream s;
298 #if GEOGRAPHICLIB_PRECISION == 4 301 using std::floor;
using std::fmod;
306 x = (ix == x && fmod(ix,
Math::real(2)) == 1) ? ix - 1 : ix;
307 s << std::fixed << std::setprecision(1) << x;
308 std::string r(s.str());
310 return r.substr(0, (std::max)(
int(r.size()) - 2, 0));
313 if (p >= 0) s << std::fixed << std::setprecision(p);
314 s << x;
return s.str();
323 static std::string
trim(
const std::string& s) {
326 end = unsigned(s.size());
327 while (beg < end && isspace(s[beg]))
329 while (beg < end && isspace(s[end - 1]))
331 return std::string(s, beg, end-beg);
358 template<
typename T>
static T
val(
const std::string& s) {
362 std::string errmsg, t(trim(s));
364 std::istringstream is(t);
366 errmsg =
"Cannot decode " + t;
369 int pos = int(is.tellg());
370 if (!(pos < 0 || pos ==
int(t.size()))) {
371 errmsg =
"Extra text " + t.substr(pos) +
" at end of " + t;
376 x = std::numeric_limits<T>::is_integer ? 0 : nummatch<T>(t);
386 static T
num(
const std::string& s) {
401 template<
typename T>
static T
nummatch(
const std::string& s) {
405 t.resize(s.length());
406 std::transform(s.begin(), s.end(), t.begin(), (int(*)(int))std::toupper);
407 for (
size_t i = s.length(); i--;)
408 t[i] =
char(std::toupper(s[i]));
409 int sign = t[0] ==
'-' ? -1 : 1;
410 std::string::size_type p0 = t[0] ==
'-' || t[0] ==
'+' ? 1 : 0;
411 std::string::size_type p1 = t.find_last_not_of(
'0');
412 if (p1 == std::string::npos || p1 + 1 < p0 + 3)
415 t = t.substr(p0, p1 + 1 - p0);
416 if (t ==
"NAN" || t ==
"1.#QNAN" || t ==
"1.#SNAN" || t ==
"1.#IND" ||
418 return Math::NaN<T>();
419 else if (t ==
"INF" || t ==
"1.#INF")
420 return sign * Math::infinity<T>();
437 template<
typename T>
static T
fract(
const std::string& s) {
438 std::string::size_type delim = s.find(
'/');
440 !(delim != std::string::npos && delim >= 1 && delim + 2 <= s.size()) ?
443 val<T>(s.substr(0, delim)) / val<T>(s.substr(delim + 1));
457 static int lookup(
const std::string& s,
char c) {
458 std::string::size_type r = s.find(
char(toupper(c)));
459 return r == std::string::npos ? -1 : int(r);
475 template<
typename ExtT,
typename IntT,
bool bigendp>
477 IntT array[],
size_t num) {
478 #if GEOGRAPHICLIB_PRECISION < 4 479 if (
sizeof(IntT) ==
sizeof(ExtT) &&
480 std::numeric_limits<IntT>::is_integer ==
481 std::numeric_limits<ExtT>::is_integer)
484 str.read(reinterpret_cast<char*>(array), num *
sizeof(ExtT));
488 for (
size_t i = num; i--;)
489 array[i] = Math::swab<IntT>(array[i]);
495 const int bufsize = 1024;
496 ExtT buffer[bufsize];
500 int n = (std::min)(k, bufsize);
501 str.read(reinterpret_cast<char*>(buffer), n *
sizeof(ExtT));
504 for (
int j = 0; j < n; ++j)
507 Math::swab<ExtT>(buffer[j]));
527 template<
typename ExtT,
typename IntT,
bool bigendp>
529 std::vector<IntT>& array) {
530 if (array.size() > 0)
531 readarray<ExtT, IntT, bigendp>(str, &array[0], array.size());
546 template<
typename ExtT,
typename IntT,
bool bigendp>
548 const IntT array[],
size_t num) {
549 #if GEOGRAPHICLIB_PRECISION < 4 550 if (
sizeof(IntT) ==
sizeof(ExtT) &&
551 std::numeric_limits<IntT>::is_integer ==
552 std::numeric_limits<ExtT>::is_integer &&
556 str.write(reinterpret_cast<const char*>(array), num *
sizeof(ExtT));
563 const int bufsize = 1024;
564 ExtT buffer[bufsize];
568 int n = (std::min)(k, bufsize);
569 for (
int j = 0; j < n; ++j)
572 Math::swab<ExtT>(ExtT(array[i++]));
573 str.write(reinterpret_cast<const char*>(buffer), n *
sizeof(ExtT));
593 template<
typename ExtT,
typename IntT,
bool bigendp>
595 std::vector<IntT>& array) {
596 if (array.size() > 0)
597 writearray<ExtT, IntT, bigendp>(str, &array[0], array.size());
615 static bool ParseLine(
const std::string& line,
616 std::string& key, std::string& val);
635 static int set_digits(
int ndigits = 0);
642 template<>
inline std::string Utility::val<std::string>(
const std::string& s)
648 template<>
inline bool Utility::val<bool>(
const std::string& s) {
649 std::string t(trim(s));
650 if (t.empty())
return false;
652 std::istringstream is(t);
654 int pos = int(is.tellg());
655 if (!(pos < 0 || pos ==
int(t.size())))
660 std::transform(t.begin(), t.end(), t.begin(), (int(*)(int))tolower);
663 if (t ==
"f" || t ==
"false")
return false;
666 if (t ==
"n" || t ==
"nil" || t ==
"no")
return false;
669 if (t ==
"off")
return false;
670 else if (t ==
"on")
return true;
673 if (t ==
"t" || t ==
"true")
return true;
676 if (t ==
"y" || t ==
"yes")
return true;
684 #if defined(_MSC_VER) 685 # pragma warning (pop) 688 #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 std::string trim(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)
static T val(const std::string &s)