fix8  version 1.4.0
Open Source C++ FIX Framework
f8utils.hpp
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------------------
2 /*
3 
4 Fix8 is released under the GNU LESSER GENERAL PUBLIC LICENSE Version 3.
5 
6 Fix8 Open Source FIX Engine.
7 Copyright (C) 2010-16 David L. Dight <fix@fix8.org>
8 
9 Fix8 is free software: you can redistribute it and / or modify it under the terms of the
10 GNU Lesser General Public License as published by the Free Software Foundation, either
11 version 3 of the License, or (at your option) any later version.
12 
13 Fix8 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
14 even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 
16 You should have received a copy of the GNU Lesser General Public License along with Fix8.
17 If not, see <http://www.gnu.org/licenses/>.
18 
19 BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO
20 THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
21 COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY
22 KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO
24 THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE,
25 YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
26 
27 IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT
28 HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED
29 ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
30 CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT
31 NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR
32 THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
33 HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34 
35 */
36 //-----------------------------------------------------------------------------------------
37 #ifndef FIX8_UTILS_HPP_
38 #define FIX8_UTILS_HPP_
39 
40 //-----------------------------------------------------------------------------------------
41 #include <iostream>
42 #include <string>
43 #include <memory>
44 #include <mutex>
45 
46 #include <Poco/DateTime.h>
47 #include <Poco/Net/SocketAddress.h>
48 
49 #ifndef _MSC_VER
50 # include <sys/ioctl.h>
51 # include <termios.h>
52 #else
53 # include <io.h>
54 #endif
55 
56 #if (FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H)
57 #include <regex.h>
58 #elif (FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO)
59 #include <Poco/RegularExpression.h>
60 #include <Poco/Exception.h>
61 #endif
62 
63 #include <fix8/f8dll.h>
64 
65 // file/line stringification
66 #define STRINGOF(x) #x
67 #define STRINGIFY(x) STRINGOF(x)
68 #define FILE_LINE __FILE__ ":" STRINGIFY(__LINE__)
69 
70 namespace FIX8 {
71 
72 //----------------------------------------------------------------------------------------
76 F8API std::string& InPlaceStrToUpper(std::string& src);
77 
81 F8API std::string& InPlaceStrToLower(std::string& src);
82 
86 F8API std::string StrToLower(const std::string& src);
87 
93 F8API int decode_dow(const std::string& from);
94 
98 F8API std::string& CheckAddTrailingSlash(std::string& source);
99 
105 F8API std::string& InPlaceReplaceInSet(const std::string& iset, std::string& src, const char repl='_');
106 
111 F8API std::string Str_error(const int err, const char *str=0);
112 
119 F8API const std::string& GetTimeAsStringMS(std::string& result, const class Tickval *tv=0, const unsigned dplaces=6, bool use_gm=false);
120 
126 inline std::string GetTimeAsStringMS(const class Tickval *tv, const unsigned dplaces=6, bool use_gm=false)
127 {
128  std::string result;
129  GetTimeAsStringMS(result, tv, dplaces, use_gm);
130  return result;
131 }
132 
137 F8API const std::string& GetTimeAsStringMini(std::string& result, const Tickval *tv);
138 
142 inline std::string GetTimeAsStringMini(const Tickval *tv)
143 {
144  std::string result;
145  GetTimeAsStringMini(result, tv);
146  return result;
147 }
148 
153 inline std::string trim(const std::string& source, const std::string& ws=" \t")
154 {
155  const size_t bgstr(source.find_first_not_of(ws));
156  return bgstr == std::string::npos
157  ? source : source.substr(bgstr, source.find_last_not_of(ws) - bgstr + 1);
158 }
159 
164 inline const std::string& trim(std::string& source, const std::string& ws=" \t")
165 {
166  const size_t bgstr(source.find_first_not_of(ws));
167  return bgstr == std::string::npos
168  ? source : source = source.substr(bgstr, source.find_last_not_of(ws) - bgstr + 1);
169 }
170 
171 //----------------------------------------------------------------------------------------
172 using Package_info = std::map<f8String, f8String>;
173 
177 
182 
183 //----------------------------------------------------------------------------------------
187 template<typename T>
188 inline void ignore_value (T val) { (void) val; }
189 
193 template<typename T>
194 inline void ignore_value (T *val) { (void) val; }
195 
196 //----------------------------------------------------------------------------------------
202 template<typename T>
203 inline T rotl(const T val, const int times) { return val << times | val >> (sizeof(T) * 8 - times); }
204 
210 template<typename T>
211 inline T rotr(const T val, const int times) { return val >> times | val << (sizeof(T) * 8 - times); }
212 
216 inline unsigned ROT13Hash (const std::string& str)
217 {
218  unsigned int hash(0);
219 
220  for (const auto& pp : str)
221  {
222  hash += pp;
223  hash -= rotl(hash, 13);
224  }
225 
226  return hash;
227 }
228 
229 //-------------------------------------------------------------------------------------------------
230 inline unsigned rothash(unsigned result, unsigned value)
231 {
232  // hash derived from http://stackoverflow.com/users/905902/wildplasser
233  return result ^= (result >> 2) ^ (result << 5) ^ (result << 13) ^ value ^ 0x80001801;
234 }
235 
236 //----------------------------------------------------------------------------------------
244 template<typename _CharT, typename _Traits, typename _Alloc>
245  inline bool operator% (const std::basic_string<_CharT, _Traits, _Alloc>& __lhs,
246  const std::basic_string<_CharT, _Traits, _Alloc>& __rhs)
247 {
248 #ifdef _MSC_VER
249  return _stricmp(__lhs.c_str(), __rhs.c_str()) == 0;
250 #else
251  return strcasecmp(__lhs.c_str(), __rhs.c_str()) == 0;
252 #endif
253 }
254 
262 template<typename _CharT, typename _Traits, typename _Alloc>
263  inline bool operator% (const _CharT* __lhs, const std::basic_string<_CharT, _Traits, _Alloc>& __rhs)
264  { return strcasecmp(__lhs, __rhs.c_str()) == 0; }
265 
273 template<typename _CharT, typename _Traits, typename _Alloc>
274  inline bool operator% (const std::basic_string<_CharT, _Traits, _Alloc>& __lhs, const _CharT* __rhs)
275 {
276 #ifdef _MSC_VER
277  return _stricmp(__lhs.c_str(), __rhs) == 0;
278 #else
279  return strcasecmp(__lhs.c_str(), __rhs) == 0;
280 #endif
281 }
282 
290 template<typename _CharT, typename _Traits, typename _Alloc>
291 inline bool operator^ (const std::basic_string<_CharT, _Traits, _Alloc>& __lhs,
292  const std::basic_string<_CharT, _Traits, _Alloc>& __rhs)
293 {
294 #ifdef _MSC_VER
295  return _stricmp(__lhs.c_str(), __rhs.c_str()) < 0;
296 #else
297  return strcasecmp(__lhs.c_str(), __rhs.c_str()) < 0;
298 #endif
299 }
300 
301 //----------------------------------------------------------------------------------------
304 F8API void create_path(const std::string& path);
305 
306 //----------------------------------------------------------------------------------------
308 class RegMatch
309 {
310 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
311  enum { SubLimit_ = 32 };
313  regmatch_t subexprs_[SubLimit_];
314  int subCnt_;
315 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
316  Poco::RegularExpression::MatchVec _matchVec;
317 #endif
318 
319 public:
322 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
323  : subexprs_(), subCnt_()
324 #endif
325  {}
326 
328  virtual ~RegMatch() {}
329 
332  unsigned SubCnt() const
333  {
334 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
335  return subCnt_;
336 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
337  return static_cast<unsigned>(_matchVec.size());
338 #endif
339  }
340 
344  size_t SubSize(const int which=0) const
345  {
346 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
347  return which < subCnt_ ? subexprs_[which].rm_eo - subexprs_[which].rm_so : -1;
348 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
349  return which < static_cast<int>(_matchVec.size()) ? _matchVec[which].length : -1;
350 #endif
351  }
352 
356  unsigned SubPos(const int which=0) const
357  {
358 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
359  return which < subCnt_ ? subexprs_[which].rm_so : -1;
360 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
361  return which < static_cast<int>(_matchVec.size()) ? static_cast<int>(_matchVec[which].offset) : -1;
362 #endif
363  }
364 
365  friend class RegExp;
366 };
367 
368 //----------------------------------------------------------------------------------------
370 class RegExp
371 {
372  const std::string pattern_;
373 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
374  enum { MaxErrLen_ = 256 };
376 
377  regex_t reg_;
378 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
379  Poco::RegularExpression * _regexp;
380 #endif
381  std::string errString;
382  int errCode_;
383 
384 public:
388  RegExp(const char *pattern, const int flags=0)
389 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
390  : pattern_(pattern)
391  {
392  if ((errCode_ = regcomp(&reg_, pattern_.c_str(), REG_EXTENDED|flags)) != 0)
393  {
394  char rbuf[MaxErrLen_];
395  regerror(errCode_, &reg_, rbuf, MaxErrLen_);
396  errString = rbuf;
397  }
398  }
399 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
400  : pattern_(pattern), _regexp()
401  {
402  try
403  {
404  _regexp = new Poco::RegularExpression(pattern, flags, true);
405  }
406  catch(const Poco::RegularExpressionException& ex)
407  {
408  errCode_ = ex.code();
409  errString = ex.message();
410  }
411  }
412 #endif
413 
415  virtual ~RegExp()
416  {
417 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
418  if (errCode_ == 0)
419  regfree(&reg_);
420 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
421  delete _regexp;
422 #endif
423  }
424 
431  int SearchString(RegMatch& match, const std::string& source, const int subExpr, const int offset=0) const
432  {
433 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
434  match.subCnt_ = 0;
435  if (regexec(&reg_, source.c_str() + offset, subExpr <= RegMatch::SubLimit_ ? subExpr : RegMatch::SubLimit_, match.subexprs_, 0) == 0)
436  while (match.subCnt_ < subExpr && match.subexprs_[match.subCnt_].rm_so != -1)
437  ++match.subCnt_;
438  return match.subCnt_;
439 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
440  match._matchVec.clear();
441  return _regexp ? _regexp->match(source, offset, match._matchVec) : 0;
442 #endif
443  }
444 
452  static std::string& SubExpr(RegMatch& match, const std::string& source, std::string& target, const int offset=0, const int num=0)
453  {
454 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
455  if (num < match.subCnt_)
456  target = source.substr(offset + match.subexprs_[num].rm_so, match.subexprs_[num].rm_eo - match.subexprs_[num].rm_so);
457 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
458  if (num < static_cast<int>(match.SubCnt()))
459  target = source.substr(offset + match.SubPos(num), match.SubSize(num));
460 #endif
461  else
462  target.empty();
463  return target;
464  }
465 
471  static std::string& Erase(RegMatch& match, std::string& source, const int num=0)
472  {
473 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
474  if (num < match.subCnt_)
475  source.erase(match.subexprs_[num].rm_so, match.subexprs_[num].rm_eo - match.subexprs_[num].rm_so);
476 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
477  if (num < static_cast<int>(match.SubCnt()))
478  source.erase(match.SubPos(num), match.SubSize(num));
479 #endif
480  return source;
481  }
482 
489  static std::string& Replace(RegMatch& match, std::string& source, const std::string& with, const int num=0)
490  {
491 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
492  if (num < match.subCnt_)
493  source.replace(match.subexprs_[num].rm_so, match.subexprs_[num].rm_eo - match.subexprs_[num].rm_so, with);
494 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
495  if (num < static_cast<int>(match.SubCnt()))
496  source.replace(match.SubPos(num), match.SubSize(num), with);
497 #endif
498  return source;
499  }
500 
507  static std::string& Replace(RegMatch& match, std::string& source, const char with, const int num=0)
508  {
509 #if FIX8_REGEX_SYSTEM == FIX8_REGEX_REGEX_H
510  if (num < match.subCnt_)
511  source.replace(match.subexprs_[num].rm_so, match.subexprs_[num].rm_eo - match.subexprs_[num].rm_so, 1, with);
512 #elif FIX8_REGEX_SYSTEM == FIX8_REGEX_POCO
513  if (num < static_cast<int>(match.SubCnt()))
514  source.replace(match.SubPos(num), match.SubSize(num), 1, with);
515 #endif
516  return source;
517  }
518 
521  const std::string& GetPattern() const { return pattern_; }
522 
525  const std::string& ErrString() const { return errString; }
526 
529  bool operator!() const { return errCode_; }
530 
533  operator void*() { return errCode_ ? 0 : this; }
534 };
535 
536 //----------------------------------------------------------------------------------------
539 {
540  bool operator()(const std::string *a, const std::string *b) const
541  { return *a ^ *b; }
542 };
543 
546 {
547  bool operator()(const std::string *a, const std::string *b) const
548  { return *a < *b; }
549 };
550 
553 {
554  bool operator()(const std::string& a, const std::string& b) const
555  { return a ^ b; }
556 };
557 
558 //----------------------------------------------------------------------------------------
563 template<typename T>
564 inline T get_value(const std::string& source)
565 {
566  std::istringstream istr(source);
567  T result((T()));
568  istr >> result;
569  return result;
570 }
571 
576 template<>
577 inline unsigned get_value(const std::string& source) { return std::stoul(source); }
578 
583 template<>
584 inline int get_value(const std::string& source) { return std::stoi(source); }
585 
590 template<>
591 inline double get_value(const std::string& source) { return std::stod(source); }
592 
597 template<>
598 inline float get_value(const std::string& source) { return std::stof(source); }
599 
604 template<>
605 inline bool get_value(const std::string& source)
606 {
607  if (source.empty())
608  return false;
609 #if !defined FIX8_XMLENTITY_STRICT_BOOL
610  return source % "true" || source % "yes" || source % "y" || source == "1";
611 #else
612  bool result(false);
613  std::istringstream istr(source);
614  istr >> std::boolalpha >> result;
615  return result;
616 #endif
617 }
618 
619 //----------------------------------------------------------------------------------------
625 template<typename T>
626 T fast_atoi(const char *str, const char term='\0')
627 {
628  T retval(0);
629  for (; *str != term; ++str)
630  retval = (retval << 3) + (retval << 1) + *str - '0';
631  return retval;
632 }
633 
634 //----------------------------------------------------------------------------------------
640 
646 template<typename T>
647 inline size_t itoa(T value, char *result, int base)
648 {
649  // check that the base if valid
650  if (base < 2 || base > 36)
651  {
652  *result = 0;
653  return 0;
654  }
655 
656  char *ptr(result), *ptr1(result);
657  T tmp_value;
658 
659  do
660  {
661  tmp_value = value;
662  value /= base;
663  *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
664  }
665  while (value);
666 
667  // Apply negative sign
668  if (tmp_value < 0)
669  *ptr++ = '-';
670  *ptr-- = 0;
671  while(ptr1 < ptr)
672  {
673  const char tmp_char(*ptr);
674  *ptr-- = *ptr1;
675  *ptr1++ = tmp_char;
676  }
677  return ::strlen(result);
678 }
679 
681 
686 template<>
687 inline size_t itoa<unsigned int>(unsigned int value, char *result, int base)
688 {
689  // check that the base if valid
690  if (base < 2 || base > 36)
691  {
692  *result = 0;
693  return 0;
694  }
695 
696  char *ptr(result), *ptr1(result);
697  unsigned int tmp_value;
698 
699  do
700  {
701  tmp_value = value;
702  value /= base;
703  *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
704  }
705  while (value);
706 
707  *ptr-- = 0;
708  while(ptr1 < ptr)
709  {
710  const char tmp_char(*ptr);
711  *ptr-- = *ptr1;
712  *ptr1++ = tmp_char;
713  }
714  return ::strlen(result);
715 }
716 
717 //----------------------------------------------------------------------------------------
727 inline fp_type fast_atof (const char *p)
728 {
729  bool frac(false);
730  fp_type sign(1.), value(0.), scale(1.);
731 
732  while (isspace(*p))
733  ++p;
734 
735  // Get sign, if any.
736  if (*p == '-')
737  {
738  sign = -1.;
739  ++p;
740  }
741  else if (*p == '+')
742  ++p;
743 
744  // Get digits before decimal point or exponent, if any.
745  while (isdigit(*p))
746  {
747  value = value * 10. + (*p - '0');
748  ++p;
749  }
750 
751  // Get digits after decimal point, if any.
752  if (*p == '.')
753  {
754  ++p;
755  fp_type mpow10(10.);
756  while (isdigit(*p))
757  {
758  value += (*p - '0') / mpow10;
759  mpow10 *= 10.;
760  ++p;
761  }
762  }
763 
764  // Handle exponent, if any.
765  if (toupper(*p) == 'E')
766  {
767  unsigned int expon(0);
768  ++p;
769 
770  // Get sign of exponent, if any.
771  if (*p == '-')
772  {
773  frac = true;
774  ++p;
775  }
776  else if (*p == '+')
777  ++p;
778 
779  // Get digits of exponent, if any.
780  while (isdigit(*p))
781  {
782  expon = expon * 10 + (*p - '0');
783  ++p;
784  }
785 #if defined FIX8_USE_SINGLE_PRECISION
786  if (expon > 38)
787  expon = 38;
788 #else
789  if (expon > 308)
790  expon = 308;
791 
792  // Calculate scaling factor.
793  while (expon >= 50)
794  {
795  scale *= 1E50;
796  expon -= 50;
797  }
798 #endif
799 
800  while (expon >= 8)
801  {
802  scale *= 1E8;
803  expon -= 8;
804  }
805  while (expon > 0)
806  {
807  scale *= 10.0;
808  expon -= 1;
809  }
810  }
811 
812  // Return signed and scaled floating point result.
813  return sign * (frac ? (value / scale) : (value * scale));
814 }
815 
816 //----------------------------------------------------------------------------------------
818 
821 extern "C" { size_t modp_dtoa(double value, char* str, int prec); }
822 
823 //----------------------------------------------------------------------------------------
824 #ifndef _MSC_VER
825 constexpr unsigned bitsum() { return 0; }
827 
832 template <typename T, typename... Args>
833 constexpr unsigned bitsum(T value, Args... args)
834  { return 1 << value | bitsum(args...); }
835 #endif
836 
837 //----------------------------------------------------------------------------------------
839 
841 template<typename T, typename B=unsigned int>
842 class ebitset
843 {
844  using integral_type = B;
846 
847 public:
849  ebitset() : a_() {}
850 
853  ebitset(const ebitset<T, B>& from) : a_(from.a_) {}
854 
857  explicit ebitset(const integral_type a) : a_(a) {}
858 
861  explicit ebitset(const T sbit) : a_((1 << sbit) - 1) {}
862 
867  {
868  if (this != &that)
869  a_ = that.a_;
870  return *this;
871  }
872 
876  integral_type has(const T sbit) const { return a_ & 1 << sbit; }
877 
881  integral_type operator&(const T sbit) const { return a_ & 1 << sbit; }
882 
886  void set(const T sbit, bool on=true) { if (on) a_ |= 1 << sbit; else a_ &= ~(1 << sbit); }
887 
890  void set(const integral_type bset) { a_ = bset; }
891 
898  int set(const std::vector<std::string>& sset, const std::string& what, bool ignorecase, bool on=true)
899  {
900  auto itr(sset.cbegin());
901  for (; itr != sset.cend(); ++itr)
902  if (ignorecase ? trim(*itr) % what : trim(*itr) == what)
903  break;
904  if (itr == sset.cend())
905  return -1;
906  const int dist(std::distance(sset.cbegin(), itr));
907  set(static_cast<T>(dist), on);
908  return dist;
909  }
910 
913  void clear(const T sbit) { a_ &= ~(1 << sbit); }
914 
916  void clearall() { a_ = 0; }
917 
920  void setall(const T sbit) { a_ = (1 << sbit) - 1; }
921 
924  integral_type get() const { return a_; }
925 
928  void operator|=(const T sbit) { a_ |= 1 << sbit; }
929 
933  ebitset& operator<<(const T sbit) { a_ |= 1 << sbit; return *this; }
934  //friend ebitset operator|(const T lbit, const T rbit) { return ebitset(lbit) |= 1 << rbit; }
935 };
936 
938 
940 template<typename T, typename B=unsigned int>
942 {
943  using integral_type = B;
945 
946 public:
948  ebitset_r() { a_ = 0; }
949 
952  ebitset_r(const ebitset_r<T, B>& from) { a_ = from.a_; }
953 
956  explicit ebitset_r(const integral_type a) { a_ = a; }
957 
960  explicit ebitset_r(const T sbit) { a_ = (1 << sbit) - 1; }
961 
966  {
967  if (this != &that)
968  a_ = that.a_;
969  return *this;
970  }
971 
975  integral_type has(const T sbit) const { return a_ & 1 << sbit; }
976 
980  integral_type operator&(const T sbit) const { return a_ & 1 << sbit; }
981 
985  void set(const T sbit, bool on=true) { if (on) a_ |= 1 << sbit; else a_ &= ~(1 << sbit); }
986 
993  bool set(const std::vector<std::string>& sset, const std::string& what, bool ignorecase=false, bool on=true)
994  {
995  auto itr(sset.cbegin());
996  for (; itr != sset.cend(); ++itr)
997  if (ignorecase ? trim(*itr) % what : trim(*itr) == what)
998  break;
999  if (itr == sset.cend())
1000  return false;
1001  set(static_cast<T>(std::distance(sset.cbegin(), itr)), on);
1002  return true;
1003  }
1004 
1007  void set(const integral_type bset) { a_ = bset; }
1008 
1011  void clear(const T sbit) { integral_type a = a_; a &= ~(1 << sbit); a_ = a; }
1012 
1014  void clearall() { a_ = 0; }
1015 
1018  void setall(const T sbit) { a_ = (1 << sbit) - 1; }
1019 
1022  integral_type get() const { return a_; }
1023 
1026  void operator|=(const T sbit) { integral_type a = a_; a |= 1 << sbit; a_ = a; }
1027 
1030  void operator&=(const T sbit) { integral_type a = a_; a &= 1 << sbit; a_ = a; }
1031 
1035  ebitset_r& operator<<(const T sbit) { a_ |= 1 << sbit; return *this; }
1036 };
1037 
1038 //----------------------------------------------------------------------------------------
1047 template<typename T>
1048 T enum_str_get(const std::vector<std::string>& sset, const std::string& what, const T def, bool ignorecase=false)
1049 {
1050  if (sset.empty())
1051  return def;
1052  auto itr(sset.cbegin());
1053  for (; itr != sset.cend(); ++itr)
1054  if (ignorecase ? *itr % what : *itr == what)
1055  break;
1056  return itr == sset.cend() ? def : static_cast<T>(std::distance(sset.begin(), itr));
1057 }
1058 
1059 //----------------------------------------------------------------------------------------
1062 F8API int get_umask();
1063 
1064 //----------------------------------------------------------------------------------------
1068 inline bool exist(const std::string& fname)
1069 {
1070 #ifdef _MSC_VER
1071  return _access(fname.c_str(), 0) == 0;
1072 #else
1073  return access(fname.c_str(), F_OK) == 0;
1074 #endif
1075 }
1076 
1077 //-----------------------------------------------------------------------------------------
1082 inline void split_path(const std::string& source, std::string& filepart, std::string& dirpart)
1083 {
1084  std::string::size_type slpos(source.find_last_of("/\\"));
1085  if (slpos == std::string::npos)
1086  filepart = source;
1087  else
1088  {
1089  filepart.assign(source.substr(slpos + 1));
1090  dirpart.assign(source.substr(0, slpos));
1091  }
1092 }
1093 
1094 //----------------------------------------------------------------------------------------
1100 inline char *CopyString(const std::string& src, char *target, unsigned limit=0)
1101 {
1102  if (!target)
1103  return nullptr;
1104  const unsigned sz(limit && static_cast<unsigned>(src.size()) > limit ? limit : (unsigned)src.size() + 1);
1105  src.copy(target, sz - 1);
1106  target[sz - 1] = 0;
1107  return target;
1108 }
1109 
1110 //----------------------------------------------------------------------------------------
1114 template <typename T>
1116 {
1117 public:
1120 
1122  virtual ~Singleton() {}
1123 
1124  Singleton(const Singleton&) = delete;
1125  Singleton& operator=(const Singleton&) = delete;
1126 
1127  static T *instance()
1128  {
1129  static T instance;
1130  return &instance;
1131  }
1132 };
1133 
1134 //---------------------------------------------------------------------------------------------------
1136 class fdinbuf : public std::streambuf
1137 {
1138  enum { _back_limit = 4, _buffer_size = 16 };
1139 
1140 protected:
1142  int _fd;
1143 
1144  virtual int_type underflow()
1145  {
1146  if (gptr() < egptr())
1147  return *gptr();
1148  int put_back_cnt(gptr() - eback());
1149  if (put_back_cnt > _back_limit)
1150  put_back_cnt = _back_limit;
1151  memcpy(_buffer + (_back_limit - put_back_cnt), gptr() - put_back_cnt, put_back_cnt);
1152 #ifdef _MSC_VER
1153  int num_read(_read (_fd, _buffer + _back_limit, _buffer_size - _back_limit));
1154 #else
1155  int num_read(read (_fd, _buffer + _back_limit, _buffer_size - _back_limit));
1156 #endif
1157  if (num_read <= 0)
1158  return -1;
1159  setg(_buffer + (_back_limit - put_back_cnt), _buffer + _back_limit, _buffer + _back_limit + num_read);
1160  return *gptr();
1161  }
1162 
1163 public:
1164  fdinbuf(int infd) : _buffer(), _fd(infd) { setg(_buffer + _back_limit, _buffer + _back_limit, _buffer + _back_limit); }
1165 };
1166 
1167 //---------------------------------------------------------------------------------------------------
1169 {
1170  bool _raw_mode = false;
1171  int _fd;
1172 #ifndef _MSC_VER
1173 #ifdef __APPLE__
1174  termios _tty_state;
1175 #else
1176  termio _tty_state;
1177 #endif
1178 #endif
1179 
1180 public:
1181  explicit tty_save_state(int fd) : _fd(fd) {}
1182 
1184  {
1185  if (&from != this)
1186  {
1187  _raw_mode = from._raw_mode;
1188  _fd = from._fd;
1189 #ifndef _MSC_VER
1190  _tty_state = from._tty_state;
1191 #endif
1192  }
1193  return *this;
1194  }
1195 
1197  {
1198  if (_raw_mode)
1199  {
1200 #ifndef _MSC_VER
1201 #ifdef __APPLE__
1202  if (ioctl(_fd, TIOCSETA, &_tty_state) < 0)
1203 #else
1204  if (ioctl(_fd, TCSETA, &_tty_state) < 0)
1205 #endif
1206  std::cerr << Str_error(errno, "Cannot reset ioctl") << std::endl;
1207  else
1208 #endif
1209  _raw_mode = false;
1210  }
1211  }
1212 
1214  {
1215  if (!_raw_mode)
1216  {
1217 #ifndef _MSC_VER
1218 #ifdef __APPLE__
1219  if (ioctl(_fd, TIOCGETA, &_tty_state) < 0)
1220 #else
1221  if (ioctl(_fd, TCGETA, &_tty_state) < 0)
1222 #endif
1223  {
1224  std::cerr << Str_error(errno, "Cannot get ioctl") << std::endl;
1225  return;
1226  }
1227 #ifdef __APPLE__
1228  termios tty_state(_tty_state);
1229 #else
1230  termio tty_state(_tty_state);
1231 #endif
1232  tty_state.c_lflag = 0;
1233  tty_state.c_cc[VTIME] = 0;
1234  tty_state.c_cc[VMIN] = 1;
1235 #ifdef __APPLE__
1236  if (ioctl(_fd, TIOCSETA, &tty_state) < 0)
1237 #else
1238  if (ioctl(_fd, TCSETA, &tty_state) < 0)
1239 #endif
1240  std::cerr << Str_error(errno, "Cannot reset ioctl") << std::endl;
1241  else
1242 #endif
1243  _raw_mode = true;
1244  }
1245  }
1246 };
1247 
1248 //----------------------------------------------------------------------------------------
1251 {
1252  std::istream *ifs_;
1253  bool nodel_;
1254 
1255 public:
1256  filestdin(std::istream *ifs, bool nodel=false) : ifs_(ifs), nodel_(nodel) {}
1257  ~filestdin() { if (!nodel_) delete ifs_; }
1258 
1259  std::istream& operator()() { return *ifs_; }
1260 };
1261 
1262 //----------------------------------------------------------------------------------------
1263 #if defined POCO_VERSION && POCO_VERSION <= 0x01040100
1264 inline bool operator==(const Poco::Net::SocketAddress &a, const Poco::Net::SocketAddress &b)
1265 {
1266  return a.host() == b.host() && a.port() == b.port();
1267 }
1268 
1269 inline bool operator!=(const Poco::Net::SocketAddress &a, const Poco::Net::SocketAddress &b)
1270 {
1271  return !(a == b);
1272 }
1273 #endif
1274 
1275 //----------------------------------------------------------------------------------------
1276 } // namespace FIX8
1277 
1278 #endif // _F8_UTILS_HPP_
bool set(const std::vector< std::string > &sset, const std::string &what, bool ignorecase=false, bool on=true)
Definition: f8utils.hpp:993
int set(const std::vector< std::string > &sset, const std::string &what, bool ignorecase, bool on=true)
Definition: f8utils.hpp:898
std::istream * ifs_
Definition: f8utils.hpp:1252
unsigned SubPos(const int which=0) const
Definition: f8utils.hpp:356
regex_t reg_
Definition: f8utils.hpp:377
F8API const std::string & GetTimeAsStringMini(std::string &result, const Tickval *tv)
size_t SubSize(const int which=0) const
Definition: f8utils.hpp:344
filestdin(std::istream *ifs, bool nodel=false)
Definition: f8utils.hpp:1256
Bitset for enums.
Definition: f8utils.hpp:842
static std::string & SubExpr(RegMatch &match, const std::string &source, std::string &target, const int offset=0, const int num=0)
Definition: f8utils.hpp:452
F8API std::string Str_error(const int err, const char *str=0)
Definition: f8utils.cpp:165
size_t modp_dtoa(double value, char *str, int prec)
Convert double to ascii.
Definition: modp_numtoa.c:68
POSIX regex wrapper class.
Definition: f8utils.hpp:370
regmatch_t subexprs_[SubLimit_]
Definition: f8utils.hpp:313
size_t itoa(T value, char *result, int base)
Fast itoa.
Definition: f8utils.hpp:647
const string & filepart(const string &source, string &where)
Definition: f8cutils.cpp:108
F8API std::string & InPlaceReplaceInSet(const std::string &iset, std::string &src, const char repl='_')
std::string trim(const std::string &source, const std::string &ws=" \t")
Definition: f8utils.hpp:153
static T * instance()
Definition: f8utils.hpp:1127
Singleton & operator=(const Singleton &)=delete
F8API int get_umask()
Definition: f8utils.cpp:184
bool operator!() const
Definition: f8utils.hpp:529
void operator|=(const T sbit)
Definition: f8utils.hpp:1026
F8API void create_path(const std::string &path)
const std::string & ErrString() const
Definition: f8utils.hpp:525
void clear(const T sbit)
Definition: f8utils.hpp:913
fp_type fast_atof(const char *p)
Definition: f8utils.hpp:727
ebitset_r(const ebitset_r< T, B > &from)
Definition: f8utils.hpp:952
Create a streambuf from an open file descriptor.
Definition: f8utils.hpp:1136
char _buffer[_buffer_size]
Definition: f8utils.hpp:1141
std::istream & operator()()
Definition: f8utils.hpp:1259
F8API std::string StrToLower(const std::string &src)
bool operator^(const std::basic_string< _CharT, _Traits, _Alloc > &__lhs, const std::basic_string< _CharT, _Traits, _Alloc > &__rhs)
Definition: f8utils.hpp:291
unsigned rothash(unsigned result, unsigned value)
Definition: f8utils.hpp:230
void setall(const T sbit)
Definition: f8utils.hpp:1018
double fp_type
Definition: f8types.hpp:51
virtual int_type underflow()
Definition: f8utils.hpp:1144
void operator|=(const T sbit)
Definition: f8utils.hpp:928
static std::string & Replace(RegMatch &match, std::string &source, const char with, const int num=0)
Definition: f8utils.hpp:507
ebitset_r(const T sbit)
Definition: f8utils.hpp:960
tty_save_state & operator=(const tty_save_state &from)
Definition: f8utils.hpp:1183
constexpr unsigned bitsum()
empty argument version
Definition: f8utils.hpp:826
static std::string & Replace(RegMatch &match, std::string &source, const std::string &with, const int num=0)
Definition: f8utils.hpp:489
Case-insensitive string comparison.
Definition: f8utils.hpp:552
virtual ~Singleton()
Dtor.
Definition: f8utils.hpp:1122
ebitset_r(const integral_type a)
Definition: f8utils.hpp:956
unsigned SubCnt() const
Definition: f8utils.hpp:332
const std::string pattern_
Definition: f8utils.hpp:372
integral_type operator&(const T sbit) const
Definition: f8utils.hpp:980
void set(const integral_type bset)
Definition: f8utils.hpp:1007
F8API f8String find_package_info_string(const f8String &what)
Definition: f8utils.cpp:301
#define F8API
Definition: f8dll.h:60
ebitset< T, B > & operator=(const ebitset< T, B > &that)
Definition: f8utils.hpp:866
F8API int decode_dow(const std::string &from)
T fast_atoi(const char *str, const char term='\0')
Definition: f8utils.hpp:626
Singleton()
Ctor.
Definition: f8utils.hpp:1119
Case-sensitive string comparison, pointer version.
Definition: f8utils.hpp:545
bool operator()(const std::string &a, const std::string &b) const
Definition: f8utils.hpp:554
F8API const Package_info & package_info()
Definition: f8utils.cpp:247
T rotr(const T val, const int times)
Definition: f8utils.hpp:211
void set(const T sbit, bool on=true)
Definition: f8utils.hpp:985
void operator&=(const T sbit)
Definition: f8utils.hpp:1030
void clear(const T sbit)
Definition: f8utils.hpp:1011
T rotl(const T val, const int times)
Definition: f8utils.hpp:203
integral_type has(const T sbit) const
Definition: f8utils.hpp:975
bool operator()(const std::string *a, const std::string *b) const
Definition: f8utils.hpp:540
RegExp(const char *pattern, const int flags=0)
Definition: f8utils.hpp:388
F8API const std::string & GetTimeAsStringMS(std::string &result, const class Tickval *tv=0, const unsigned dplaces=6, bool use_gm=false)
int SearchString(RegMatch &match, const std::string &source, const int subExpr, const int offset=0) const
Definition: f8utils.hpp:431
void clearall()
Clear all bits.
Definition: f8utils.hpp:1014
virtual ~RegExp()
Dtor. Destroys internal compiled expression.
Definition: f8utils.hpp:415
T enum_str_get(const std::vector< std::string > &sset, const std::string &what, const T def, bool ignorecase=false)
Definition: f8utils.hpp:1048
std::atomic< T > f8_atomic
Definition: thread.hpp:55
T get_value(const std::string &source)
Definition: f8utils.hpp:564
ebitset_r & operator<<(const T sbit)
Definition: f8utils.hpp:1035
char * CopyString(const std::string &src, char *target, unsigned limit=0)
Definition: f8utils.hpp:1100
static std::string & Erase(RegMatch &match, std::string &source, const int num=0)
Definition: f8utils.hpp:471
ebitset & operator<<(const T sbit)
Definition: f8utils.hpp:933
F8API std::string & InPlaceStrToUpper(std::string &src)
F8API std::string & InPlaceStrToLower(std::string &src)
Atomic bitset for enums.
Definition: f8utils.hpp:941
void split_path(const std::string &source, std::string &filepart, std::string &dirpart)
Definition: f8utils.hpp:1082
const std::string & GetPattern() const
Definition: f8utils.hpp:521
bool operator%(const std::basic_string< _CharT, _Traits, _Alloc > &__lhs, const std::basic_string< _CharT, _Traits, _Alloc > &__rhs)
Definition: f8utils.hpp:245
F8API std::string & CheckAddTrailingSlash(std::string &source)
ebitset(const integral_type a)
Definition: f8utils.hpp:857
integral_type has(const T sbit) const
Definition: f8utils.hpp:876
Abstract file or stdin input.
Definition: f8utils.hpp:1250
fdinbuf(int infd)
Definition: f8utils.hpp:1164
A class to contain regex matches using RegExp.
Definition: f8utils.hpp:308
void set(const integral_type bset)
Definition: f8utils.hpp:890
virtual ~RegMatch()
Ctor.
Definition: f8utils.hpp:328
integral_type a_
Definition: f8utils.hpp:845
void clearall()
Clear all bits.
Definition: f8utils.hpp:916
RegMatch()
Ctor.
Definition: f8utils.hpp:321
ebitset_r()
Ctor.
Definition: f8utils.hpp:948
f8_atomic< integral_type > a_
Definition: f8utils.hpp:944
void ignore_value(T val)
Definition: f8utils.hpp:188
size_t itoa< unsigned int >(unsigned int value, char *result, int base)
Fast itoa - unsigned int specialisation.
Definition: f8utils.hpp:687
void setall(const T sbit)
Definition: f8utils.hpp:920
void set(const T sbit, bool on=true)
Definition: f8utils.hpp:886
std::string errString
Definition: f8utils.hpp:381
ebitset_r< T, B > & operator=(const ebitset_r< T, B > &that)
Definition: f8utils.hpp:965
ebitset()
Ctor.
Definition: f8utils.hpp:849
bool exist(const std::string &fname)
Definition: f8utils.hpp:1068
unsigned ROT13Hash(const std::string &str)
Definition: f8utils.hpp:216
std::string f8String
Definition: f8types.hpp:47
bool operator()(const std::string *a, const std::string *b) const
Definition: f8utils.hpp:547
std::map< f8String, f8String > Package_info
Definition: f8utils.hpp:172
ebitset(const ebitset< T, B > &from)
Definition: f8utils.hpp:853
ebitset(const T sbit)
Definition: f8utils.hpp:861
Case-insensitive string comparison, pointer version.
Definition: f8utils.hpp:538
integral_type operator&(const T sbit) const
Definition: f8utils.hpp:881