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();
297 return x < 0 ? std::string(
"-inf") :
298 (x > 0 ? std::string(
"inf") : std::string(
"nan"));
299 std::ostringstream s;
300 #if GEOGRAPHICLIB_PRECISION == 4 303 using std::floor;
using std::fmod;
308 x = (ix == x && fmod(ix,
Math::real(2)) == 1) ? ix - 1 : ix;
309 s << std::fixed << std::setprecision(1) << x;
310 std::string r(s.str());
312 return r.substr(0, (std::max)(
int(r.size()) - 2, 0));
315 if (p >= 0) s << std::fixed << std::setprecision(p);
316 s << x;
return s.str();
325 static std::string
trim(
const std::string& s) {
328 end = unsigned(s.size());
329 while (beg < end && isspace(s[beg]))
331 while (beg < end && isspace(s[end - 1]))
333 return std::string(s, beg, end-beg);
360 template<
typename T>
static T
val(
const std::string& s) {
364 std::string errmsg, t(trim(s));
366 std::istringstream is(t);
368 errmsg =
"Cannot decode " + t;
371 int pos = int(is.tellg());
372 if (!(pos < 0 || pos ==
int(t.size()))) {
373 errmsg =
"Extra text " + t.substr(pos) +
" at end of " + t;
378 x = std::numeric_limits<T>::is_integer ? 0 : nummatch<T>(t);
388 static T num(const
std::
string& s) {
403 template<
typename T>
static T
nummatch(
const std::string& s) {
407 for (std::string::iterator p = t.begin(); p != t.end(); ++p)
408 *p =
char(std::toupper(*p));
409 for (
size_t i = s.length(); i--;)
410 t[i] =
char(std::toupper(s[i]));
411 int sign = t[0] ==
'-' ? -1 : 1;
412 std::string::size_type p0 = t[0] ==
'-' || t[0] ==
'+' ? 1 : 0;
413 std::string::size_type p1 = t.find_last_not_of(
'0');
414 if (p1 == std::string::npos || p1 + 1 < p0 + 3)
417 t = t.substr(p0, p1 + 1 - p0);
418 if (t ==
"NAN" || t ==
"1.#QNAN" || t ==
"1.#SNAN" || t ==
"1.#IND" ||
420 return Math::NaN<T>();
421 else if (t ==
"INF" || t ==
"1.#INF")
422 return sign * Math::infinity<T>();
441 template<
typename T>
static T
fract(
const std::string& s) {
442 std::string::size_type delim = s.find(
'/');
444 !(delim != std::string::npos && delim >= 1 && delim + 2 <= s.size()) ?
447 val<T>(s.substr(0, delim)) / val<T>(s.substr(delim + 1));
461 static int lookup(
const std::string& s,
char c) {
462 std::string::size_type r = s.find(
char(std::toupper(c)));
463 return r == std::string::npos ? -1 : int(r);
477 static int lookup(
const char* s,
char c) {
478 const char* p = std::strchr(s, std::toupper(c));
479 return p != NULL ? int(p - s) : -1;
495 template<
typename ExtT,
typename IntT,
bool bigendp>
496 static void readarray(std::istream& str, 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)
503 str.read(reinterpret_cast<char*>(array), num *
sizeof(ExtT));
507 for (
size_t i = num; i--;)
508 array[i] = Math::swab<IntT>(array[i]);
514 const int bufsize = 1024;
515 ExtT buffer[bufsize];
519 int n = (std::min)(k, bufsize);
520 str.read(reinterpret_cast<char*>(buffer), n *
sizeof(ExtT));
523 for (
int j = 0; j < n; ++j)
526 Math::swab<ExtT>(buffer[j]));
546 template<
typename ExtT,
typename IntT,
bool bigendp>
547 static void readarray(std::istream& str, std::vector<IntT>& array) {
548 if (array.size() > 0)
549 readarray<ExtT, IntT, bigendp>(str, &array[0], array.size());
564 template<
typename ExtT,
typename IntT,
bool bigendp>
565 static void writearray(std::ostream& str,
const IntT array[],
size_t num)
567 #if GEOGRAPHICLIB_PRECISION < 4 568 if (
sizeof(IntT) ==
sizeof(ExtT) &&
569 std::numeric_limits<IntT>::is_integer ==
570 std::numeric_limits<ExtT>::is_integer &&
574 str.write(reinterpret_cast<const char*>(array), num *
sizeof(ExtT));
581 const int bufsize = 1024;
582 ExtT buffer[bufsize];
586 int n = (std::min)(k, bufsize);
587 for (
int j = 0; j < n; ++j)
590 Math::swab<ExtT>(ExtT(array[i++]));
591 str.write(reinterpret_cast<const char*>(buffer), n *
sizeof(ExtT));
611 template<
typename ExtT,
typename IntT,
bool bigendp>
612 static void writearray(std::ostream& str, std::vector<IntT>& array) {
613 if (array.size() > 0)
614 writearray<ExtT, IntT, bigendp>(str, &array[0], array.size());
636 static bool ParseLine(
const std::string& line,
637 std::string& key, std::string& value,
655 static bool ParseLine(
const std::string& line,
656 std::string& key, std::string& value);
675 static int set_digits(
int ndigits = 0);
682 template<>
inline std::string Utility::val<std::string>(
const std::string& s)
688 template<>
inline bool Utility::val<bool>(
const std::string& s) {
689 std::string t(trim(s));
690 if (t.empty())
return false;
693 std::istringstream is(t);
695 int pos = int(is.tellg());
696 if (!(pos < 0 || pos ==
int(t.size())))
702 for (std::string::iterator p = t.begin(); p != t.end(); ++p)
703 *p =
char(std::tolower(*p));
706 if (t ==
"f" || t ==
"false")
return false;
709 if (t ==
"n" || t ==
"nil" || t ==
"no")
return false;
712 if (t ==
"off")
return false;
713 else if (t ==
"on")
return true;
716 if (t ==
"t" || t ==
"true")
return true;
719 if (t ==
"y" || t ==
"yes")
return true;
727 #if defined(_MSC_VER) 728 # pragma warning (pop) 731 #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 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)