Stringed Instruments, Inheritance Demo
cmpslib.h
1 #pragma once
2 
3 #include <cxxabi.h>
4 #include <bitset>
5 #include <time.h>
6 #include <string> // string class
7 #include <string.h> // c-string library
8 #include <sstream> // ostringstream
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <iostream>
12 #include <fstream> // c file output
13 #include <stdarg.h>
14 #include <typeinfo> // find names of ADTs at runtime
15 #include <limits.h> // min and max values for dataytypes
16 #include <limits>
17 #include <ios>
18 #include <float.h>
19 #include <math.h>
20 #include <iomanip>
21 #include <stdexcept> // exception handling ..
22 #include <signal.h> // for catching the segfaults
23 #include <random>
24 using namespace std;
25 
26 
27 
28 // this one is used by the prompt functions you wont need it
29 template <typename CharT>
30 std::streamsize ignore_line (std::basic_istream<CharT>& in, bool always_discard = false );
31 
32 
33 
34 /**************************************
35  user input
36  ***************************************/
37 /*
38  string PromptForString(string input)
39  dispay the text 'input'
40 
41  put put a prompt
42  take the text (up to 499 chars) and return it as a string
43  */
44 inline string PromptForString(string input)
45  {
46  ignore_line( cin );// clear the buffer if needed
47  while (true)
48  {
49  cout << input ;
50  string user_input;
51  getline(cin, user_input);
52  return user_input;
53  }
54  }
55 
56 
57 
58 /* use cout to send the first parameter "text" to the console
59  take in input from the user until they enter a valid integer
60  value between min and max , the 2nd and 3rd parameters */
61 inline int PromptForInt( string text, int minval=INT_MIN, int maxval=INT_MAX)
62  {
63  string input;
64  int valid_int;
65  while (1)
66  {
67  input = PromptForString(text);
68  try
69  {
70  valid_int = stod(input);
71  if (valid_int < minval || valid_int > maxval)
72  {
73  cout << "The entered value must be with the range " << minval << " to " << maxval << endl;
74  }
75  else
76  {
77  return valid_int;
78  }
79 
80  }
81  catch (...)
82  {
83  cout << "invalid value\n" << endl;
84  ignore_line(cin);
85  }
86  }
87  }
88 
89 
90 /* use cout to send the first parameter "text" to the console
91  take in input from the user until they enter a valid double
92  value between min and max , the 2nd and 3rd parameters */
93 inline double PromptForDouble( string text,double minval=DBL_MIN, double maxval=DBL_MAX)
94  {
95  string input;
96  double valid_double;
97  while (1)
98  {
99  input = PromptForString(text);
100  try
101  {
102  valid_double = std::stod(input);
103  if (valid_double < minval || valid_double > maxval)
104  {
105  cout << "The entered value must be with the range " << minval << " to " << maxval << endl;
106  }
107  else
108  {
109  return valid_double;
110  }
111 
112  }
113  catch (...)
114  {
115 
116  cout << "invalid value\n" << endl;
117  }
118  }
119  }
120 
121 
122 
123 /* use cout to send the first parameter "text" to the console
124  take in input from the user and store it in the second parameter */
125 
126 template <class T>
127 void Prompt (string prompt, T & val)
128  {
129 
130  cout << prompt;
131  cin >> val;
132  while(cin.fail())
133  {
134  cin.clear();
135  cin.ignore(numeric_limits<streamsize>::max(), '\n');
136  cout << prompt;
137  cin >> val;
138  }
139  }
140 
141 
142 /*
143  bool PromptYN(string input)
144  display the string 'input'
145  give the user a prompt
146  if they type Y or y return true
147  if they type N or n return false
148  if they type anything else
149  keep repeating till they type Y,y,N or n
150 
151 usage:
152 if ( PromptYN("Do you like SPAM & eggs?")
153 cout << "you answered Y or y" << endl;
154 else
155 cout << "you answered N or n" << endl;
156  */
157 
158 
159 inline bool PromptYN(string input)
160  {
161  while (true)
162  {
163  cout << input << " (Y/N)"<< endl;
164  ignore_line( cin ); // clear the buffer if needed
165  string user_input;
166  cin >> user_input;
167  if ( user_input == "Y" || user_input =="y")
168  {
169  return true;
170  }
171  if (user_input == "N" || user_input =="n")
172  {
173  return false;
174  }
175  }
176  }
177 
178 
179 
180 
181 
182 
183 /*********************************************
184  system stuff
185  *********************************************/
186 
187 // Do nothing for a period of time
188 // // used to slow the operation of programs
189 // // the parameter passed in will be approximatley in 100ths of a second
190 // // 25 -> quarter of a second, 50 -> half a second
191 inline void WaitHundredth(int time)
192  {
193  struct timespec tim, tim2;
194  tim.tv_sec = 0;
195  tim.tv_nsec = time*10000000;
196  nanosleep(&tim , &tim2);
197  }
198 
199 
200 // // clear the screen
201 #define ClearScreen() system("clear")
202 
203 
204 /*
205  GetTime()
206  returns the current time as a formatted char array
207  The returned string has the following format:
208  Www Mmm dd hh:mm:ss yyyy
209  Where Www is the weekday, Mmm the month in letters, dd the day of the month, hh:mm:ss the time, and yyyy the year.
210  The string is followed by a new-line character ('\n') and the terminating null-character.
211  */
212 inline char * GetTime()
213  {
214  time_t rawtime = time(0);
215  struct tm * timeinfo;
216 
217  timeinfo = localtime ( &rawtime );
218  return asctime (timeinfo);
219  }
220 
221 
222 
223 
224 /****************************************
225  Numberic fuctions
226 
227  *****************************************/
228 
229 /*
230  this will try to convert a string to in integer
231  may throw and exception if it cant do it
232  */
233 
234 inline int StringToInteger( string input)
235  {
236  return stoi(input);
237  }
238 
239 inline double StringToDouble( string input )
240  {
241  return stod(input);
242  }
243 
244 
245 inline bool StringToBool(string input)
246  {
247  if(input=="true" || input =="1")
248  {
249  return true;
250  }
251 
252  if(input=="false" || input =="0")
253  {
254  return false;
255  }
256 
257  return false;
258  }
259 
260 
261 
262 /*
263  compare some floating point numbers
264  this should work for type double as well
265 
266  it is difficult to compare for equality so this will tell us if they are within
267  a distance of each other the default for that value is .0005
268 
269  */
270 inline bool VeryClose(float A, float B, float epsilon = 0.0005f)
271  {
272  return (fabs(A - B) < epsilon);
273  }
274 
275 
276 
277 
278 /*
279  this will try to convert a string to in integer
280  may throw and exception if it cant do it
281  */
282 template <typename T>
283 string NumberToString ( T Number )
284  {
285  ostringstream ss;
286  ss << Number;
287  return ss.str();
288  }
289 
290 
291 inline int CreateRandomNumber(int min, int max)
292  {
293  std::random_device rd;
294  std::mt19937 gen(rd());
295  std::uniform_int_distribution<> dis(min,max);
296  return (dis(gen));
297 
298  /*
299  if ( 1804289383 == rand())
300  srand(time(NULL));
301  return ( ( rand() % (max-min+1) ) + min);
302  */
303 
304  }
305 
306 inline bool IsNumber(string str)
307  {
308  for (unsigned int i = 0; i < str.length(); i++)
309  {
310  if (! isdigit(str[i]))
311  {
312  return false;
313  }
314 
315  }
316  return true;
317  }
318 
319 inline bool IsInteger(string input)
320  {
321  try
322  {
323  int temp = stoi(input);
324  temp++; // to avoid unused var warning
325  }
326  catch(...)
327  {
328  return false;
329  }
330  return true;
331  }
332 
333 
334 inline bool IsDouble(string input)
335  {
336 
337  try
338  {
339  double temp = stod(input);
340  temp++; // to avoid unused var warning
341  }
342  catch(...)
343  {
344  return false;
345  }
346  return true;
347  }
348 
349 
350 
351 inline string PassFail(bool in)
352  {
353  return (in) ? "Pass":"Fail";
354  }
355 inline string PF(bool in)
356  {
357  return (in) ? "Pass":"Fail";
358  }
359 
360 
361 /***************************************
362  console functions
363  ****************************************/
364 
365 
366 /*
367  returns the input string wrapped in the commands to change color , display the text and change back to white
368 
369  cout << "the cat is " << RED("named felix" << " the cat" << endl;
370 
371  only "named felix" will be red
372  */
373 
374 inline string RED(string input)
375  {
376  return string("\033[1;31m"+input+"\033[0m");
377  }
378 
379 inline string GREEN(string input)
380  {
381  return string("\033[1;32m"+input+"\033[0m");
382  }
383 
384 inline string YELLOW(string input)
385  {
386  return string("\033[1;33m"+input+"\033[0m");
387  }
388 
389 inline string BLUE(string input)
390  {
391  return string("\033[1;34m"+input+"\033[0m");
392  }
393 
394 inline string MAGENTA(string input)
395  {
396  return string("\033[1;35m"+input+"\033[0m");
397  }
398 
399 inline string CYAN(string input)
400  {
401  return string("\033[1;36m"+input+"\033[0m");
402  }
403 
404 
405 
406 
407 /* returns a string that when pushed to cout will change the console output color
408  you will probably want to set it back white at some point */
409 
410 inline string ChangeToRed()
411  {
412  return string("\033[1;31m");
413  }
414 inline string ChangeToGreen()
415  {
416  return string("\033[1;32m");
417  }
418 inline string ChangeToYellow()
419  {
420  return string("\033[1;33m");
421  }
422 inline string ChangeToBlue()
423  {
424  return string("\033[1;34m");
425  }
426 inline string ChangeToMagenta()
427  {
428  return string("\033[1;35m");
429  }
430 inline string ChangeToCyan()
431  {
432  return string("\033[1;36m");
433  }
434 inline string ChangeToWhite()
435  {
436  return string("\033[0m");
437  }
438 
439 
440 
441 /* move the cursor to the position indcated by the row and column.. Note the offset is 1 not 0 */
442 inline void PositionCursor(int row,int col)
443  {
444  printf("\033[%i;%iH",row+1,col+1);
445  }
446 
447 
448 
449 /*********************************************************************************************************************
450  **********************************************************************************************************************
451 
452  Logging functions and macros
453 
454  you need to define LOGLEVEL 0-3
455  LOGLEVEL not defined all logging functions are left out of compiled code
456  0 none all logging functions are left out of compiled code
457  1 low level LogLow function calls only
458  2 med level LogLow, LogMed , LogEnd ,LogStart
459  3 high level everything
460 
461  you can do it with something like
462 #define LOGLEVEL 2
463 
464 
465 you MUST have the following in any main.cpp (AND ONLY IN THE MAIN) where you want to use the logging
466 
467 #include "logger.h"
468 struct LOGGER_DATA LGDATA; // create a global instance of this struct .. needed by logging library
469 
470 
471  **********************************************************************************************************************
472  **********************************************************************************************************************/
473 
474 #if LOGLEVEL < 1 || (! defined(LOGLEVEL))
475 // we wil put in some stubs to make all the logging functions basically do nothing
476 #define LOGGER_DATA
477 #define LoggerSetup(...)
478 #define LoggerSetUpLog(...) //do nothing
479 #define LogLow(...) //do nothing
480 #define LogMed(...) //do nothing
481 #define LogHigh(...) //do nothing
482 #define LogPos() // do nothing
483 #define LogStart(...)
484 #define LogEnd(...)
485 #define LogEndReturning(...)
486 // end all the stubs
487 #endif // LOGLEVEL not defined or 0
488 
489 
490 
491 
492 /* here we will put in the actual functions and working logging */
493 #if LOGLEVEL > 0
494 
495 
496 
497 struct LOGGER_DATA
498  {
499  FILE * LF;
500  int INDENT_COUNT;
501  char INDENT_BUFFER[1000];
502  char FN[100];
503  int Frame;
504  int initialized;
505  LOGGER_DATA() {FN[0]=0;}
506  };
507 typedef struct LOGGER_DATA LOGGER_DATA;
508 
509 extern LOGGER_DATA LGDATA;
510 
511 
512 
513 #define GET_MACRO(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, NAME, ...) NAME
514 
515 #define LogStart(...) GET_MACRO(_0, ##__VA_ARGS__, LogStart10, LogStart9, LogStart8, LogStart7, LogStart6, LogStart5, LogStart4, LogStart3, LogStart2, LogStart1, LogStart0)(__VA_ARGS__)
516 #define LogStart0() LoggerStart(__PRETTY_FUNCTION__,__LINE__);
517 #define LogStart1(a) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a));
518 #define LogStart2(a,b) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b));
519 #define LogStart3(a,b,c) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c));
520 #define LogStart4(a,b,c,d) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d));
521 #define LogStart5(a,b,c,d,e) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e));
522 #define LogStart6(a,b,c,d,e,f) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f));
523 #define LogStart7(a,b,c,d,e,f,g) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f),AsString(g));
524 #define LogStart8(a,b,c,d,e,f,g,h) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f),AsString(g),AsString(h));
525 #define LogStart9(a,b,c,d,e,f,g,h,i) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f),AsString(g),AsString(h),AsString(i));
526 #define LogStart10(a,b,c,d,e,f,g,h,i,j) LoggerStart(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f),AsString(g),AsString(h),AsString(i),AsString(j));
527 
528 #define LogEnd(...) GET_MACRO(_0, ##__VA_ARGS__, LogEnd10, LogEnd9, LogEnd8, LogEnd7, LogEnd6, LogEnd5, LogEnd4, LogEnd3, LogEnd2, LogEnd1, LogEnd0)(__VA_ARGS__)
529 #define LogEnd0() LoggerEnd(__PRETTY_FUNCTION__,__LINE__);
530 #define LogEnd1(a) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a));
531 #define LogEnd2(a,b) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b));
532 #define LogEnd3(a,b,c) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c));
533 #define LogEnd4(a,b,c,d) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d));
534 #define LogEnd5(a,b,c,d,e) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e));
535 #define LogEnd6(a,b,c,d,e,f) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f));
536 #define LogEnd7(a,b,c,d,e,f,g) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f),AsString(g));
537 #define LogEnd8(a,b,c,d,e,f,g,h) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f),AsString(g),AsString(h));
538 #define LogEnd9(a,b,c,d,e,f,g,h,i) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f),AsString(g),AsString(h),AsString(i));
539 #define LogEnd10(a,b,c,d,e,f,g,h,i,j) LoggerEnd(__PRETTY_FUNCTION__,__LINE__,AsString(a),AsString(b),AsString(c),AsString(d),AsString(e),AsString(f),AsString(g),AsString(h),AsString(i),AsString(j));
540 
541 #define LogEndReturning(a) LoggerEndReturning(__PRETTY_FUNCTION__,__LINE__,a)
542 
543 #define LogPos() LoggerLow(__PRETTY_FUNCTION__,__LINE__,"")
544 #define LogLow(a, ...) LoggerLow(__PRETTY_FUNCTION__,__LINE__,a,##__VA_ARGS__)
545 #define LogMed(a, ...) LoggerMed(__PRETTY_FUNCTION__,__LINE__,a,##__VA_ARGS__)
546 #define LogHigh(a, ...) LoggerHigh(__PRETTY_FUNCTION__,__LINE__,a,##__VA_ARGS__)
547 
548 
549 inline void LoggerOpen()
550  {
551  if( LGDATA.LF)
552  {
553  return;
554  }
555  if (strlen(LGDATA.FN) ==0)
556  {
557  cerr << "\nYou do not seem to have set up the logging in your main properly, look at the examples\n no i dont have a log file name \n";
558  exit(0);
559  }
560 
561  LGDATA.LF =fopen(LGDATA.FN,"a+");
562  if (LGDATA.LF == NULL)
563  {
564  cerr << "Could not open the logfile \""<< LGDATA.FN << "\", you may not have write permssions to that file: " << LGDATA.FN << endl;
565  exit(0);
566  }
567  }
568 
569 inline void LoggerClose()
570  {
571  if(! LGDATA.LF)
572  {
573  return;
574  }
575  fclose ( LGDATA.LF );
576  LGDATA.LF = NULL;
577  }
578 
579 inline void LoggerSetIndent(int in)
580  {
581  LGDATA.INDENT_COUNT+=in;
582 
583  if (LGDATA.INDENT_COUNT <0)
584  {
585  LGDATA.INDENT_COUNT=0;
586  }
587 
588  if (LGDATA.INDENT_COUNT >999)
589  {
590  LGDATA.INDENT_COUNT=999;
591  }
592 
593  memset(LGDATA.INDENT_BUFFER,' ',LGDATA.INDENT_COUNT);
594  LGDATA.INDENT_BUFFER[LGDATA.INDENT_COUNT]=0;
595  }
596 
597 // varidac functions for the logging to log end of function
598 
599 // WriteParams handle all the values for all the parameters for LogStart and LogEnd after the first one
600 //inline void WriteParams() {}
601 
602 //template <typename T, typename... Args>
603 //void WriteParams(const T & val,const Args... args)
604 // {
605 // fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,AsString(val).c_str());
606 // WriteParams(args...);
607 // }
608 
609 
610 inline void LoggerEnd(const char * fn,const int line ,string a="",string b="",string c="",string d="",string e="",string f="",string g="",string h="",string i="",string j="")
611  {
612  LoggerOpen();
613  fprintf(LGDATA.LF,"%sEnd -- frame(%d) %s\n",LGDATA.INDENT_BUFFER,LGDATA.Frame,fn);
614 
615  if(a.length() >0)
616  {
617  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,a.c_str());
618  }
619  if(b.length() >0)
620  {
621  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,b.c_str());
622  }
623  if(c.length() >0)
624  {
625  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,c.c_str());
626  }
627  if(d.length() >0)
628  {
629  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,d.c_str());
630  }
631  if(e.length() >0)
632  {
633  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,e.c_str());
634  }
635  if(f.length() >0)
636  {
637  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,f.c_str());
638  }
639  if(g.length() >0)
640  {
641  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,g.c_str());
642  }
643  if(h.length() >0)
644  {
645  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,h.c_str());
646  }
647  if(i.length() >0)
648  {
649  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,i.c_str());
650  }
651  if(j.length() >0)
652  {
653  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,j.c_str());
654  }
655 
656  LoggerSetIndent(-2);
657 
658  if (0 == LGDATA.INDENT_COUNT)
659  {
660  fprintf(LGDATA.LF,"\n\n");
661  }
662  LoggerClose();
663  LGDATA.Frame--;
664  }
665 
666 inline void LoggerStart(const char * fn,const int line,string a="",string b="",string c="",string d="",string e="",string f="",string g="",string h="",string i="",string j="")
667  {
668  LoggerOpen();
669  LoggerSetIndent(2);
670 
671  LGDATA.Frame++;
672  fprintf(LGDATA.LF,"%sStart -- frame(%d) %s\n",LGDATA.INDENT_BUFFER,LGDATA.Frame,fn);
673 
674  if(a.length() >0)
675  {
676  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,a.c_str());
677  }
678  if(b.length() >0)
679  {
680  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,b.c_str());
681  }
682  if(c.length() >0)
683  {
684  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,c.c_str());
685  }
686  if(d.length() >0)
687  {
688  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,d.c_str());
689  }
690  if(e.length() >0)
691  {
692  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,e.c_str());
693  }
694  if(f.length() >0)
695  {
696  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,f.c_str());
697  }
698  if(g.length() >0)
699  {
700  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,g.c_str());
701  }
702  if(h.length() >0)
703  {
704  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,h.c_str());
705  }
706  if(i.length() >0)
707  {
708  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,i.c_str());
709  }
710  if(j.length() >0)
711  {
712  fprintf(LGDATA.LF,"%sparam: %s\n",LGDATA.INDENT_BUFFER,j.c_str());
713  }
714 
715  LoggerClose();
716  }
717 
718 
719 
720 
721 inline void segfault_sigaction(int signal, siginfo_t *si, void *arg)
722  {
723  psignal(signal,"\n\nYour program experienced an error\nsignal:\n");
724  psiginfo(si,"siginfo_t:\n");
725  exit(0);
726  }
727 
728 inline void LoggerSetUpLog(const char * filename, bool append=false)
729  {
730  strncpy(LGDATA.FN,filename,100);
731  LGDATA.LF=NULL;
732  LGDATA.INDENT_COUNT=0;
733  LGDATA.Frame=0;
734 
735  if (! append)
736  {
737  LGDATA.LF = fopen(LGDATA.FN,"w+");
738  if (LGDATA.LF == NULL)
739  {
740  cerr << "Could not open the logfile, you may not have write permssions to the file: " << LGDATA.FN << endl;
741  exit(0);
742  }
743 
744 
745  }
746  else
747  {
748  LoggerOpen();
749  }
750 
751  fprintf(LGDATA.LF,"log file \"%s\" opened\n",LGDATA.FN );
752  LoggerClose();
753 
754  struct sigaction sa;
755  int size = sizeof(sa);
756  memset(&sa, 0, size);
757  sigemptyset(&sa.sa_mask);
758  sa.sa_sigaction = segfault_sigaction;
759  sa.sa_flags = SA_SIGINFO;
760 
761  sigaction(SIGSEGV, &sa, NULL);
762  }
763 
764 
765 
766 template<class T>
767 void* GetAddress( T & in)
768  {
769  return & in;
770  }
771 
772 template<class T>
773 void* GetAddress( T * in)
774  {
775  return ((void*) in);
776  }
777 
778 
779 template <typename T>
780 inline string ValueAsString(T & in)
781  {
782 
783  int status=0;
784  char * tmp;
785  tmp = abi::__cxa_demangle( typeid(T).name(),0,0,&status);
786  string name(tmp);
787  free (tmp);
788 
789 
790  ostringstream out;
791  if (name=="int" )
792  {
793  out << * ((int *) &in );
794  return out.str();
795  }
796 
797  if (name=="unsigned long" )
798  {
799  out << * ((unsigned long *) &in );
800  return out.str();
801  }
802 
803  if (name=="long" )
804  {
805  out << * ((long *) &in );
806  return out.str();
807  }
808 
809  if (name=="long long" )
810  {
811  out << * ((long long *) &in );
812  return out.str();
813  }
814 
815  if (name=="unsigned long long" )
816  {
817  out << * ((unsigned long long *) &in );
818  return out.str();
819  }
820 
821  if (name=="short" )
822  {
823  out << * ((short *) &in );
824  return out.str();
825  }
826 
827  if (name=="unsigned short" )
828  {
829  out << * ((unsigned short *) &in );
830  return out.str();
831  }
832 
833  if (name=="double" )
834  {
835  out << * ((double *) &in );
836  return out.str();
837  }
838 
839  if (name=="long double" )
840  {
841  out << * ((long double *) &in );
842  return out.str();
843  }
844 
845  if (name=="char" )
846  {
847  out << * ((char *) &in );
848  return out.str();
849  }
850 
851  if (name=="char *" )
852  {
853  out << * ((char *) &in );
854  return out.str();
855  }
856 
857  if (name=="char const*" )
858  {
859  out << * ((char const *) &in );
860  return out.str();
861  }
862 
863  if (name=="unsigned char" )
864  {
865  out << * ((unsigned char *) &in );
866  return out.str();
867  }
868 
869  if (name=="bool" )
870  {
871  out << boolalpha << * ((bool *) &in );
872  return out.str();
873  }
874 
875  if (name=="std::string" )
876  {
877  out << * ((std::string *) &in );
878  return out.str();
879  }
880 
881  if (name=="std::istream" )
882  {
883  out << "cant display value of std::istream" ;
884  return out.str();
885  }
886 
887  if (name=="std::ostream" )
888  {
889  out << "cant display value of std::ostream" ;
890  return out.str();
891  }
892 
893  if (name=="std::ifstream" )
894  {
895  out << "cant display value of std::ifstream" ;
896  return out.str();
897  }
898 
899  if (name=="std::ofstream" )
900  {
901  out << "cant display value of std::ofstream" ;
902  return out.str();
903  }
904 
905  return string("unknown type <" + name + ">, cant display value try converting it to a string or overoad ostream << \n");
906  }
907 template <class T>
908 string GetClassName(T&input)
909 {
910  int status=0;
911  char * tmp;
912  tmp = abi::__cxa_demangle( typeid(T).name(),0,0,&status);
913  string name(tmp);
914  free (tmp);
915 
916  return name;
917 }
918 
919 template <class T>
920 string GetClassName(T * input)
921 {
922  int status=0;
923  char * tmp;
924  tmp = abi::__cxa_demangle( typeid(T).name(),0,0,&status);
925  string name(tmp);
926  free (tmp);
927  name += " pointer";
928  return name;
929 }
930 
931 
932 
933 
934 template <class T>
935 string AsString(T & input)
936  {
937  string name = GetClassName(input);
938  ostringstream out;
939  out << name<< " address:" << ((void*) & input) << " value:" << ValueAsString(input);
940  return out.str();
941  }
942 
943 template <class T>
944 string AsString(T *input)
945  {
946  string name = GetClassName(input);
947  ostringstream out;
948  if(input == nullptr)
949  {
950  out << name << "* address:" << ((void *)input) << " points_to_value:nullptr";
951  }
952  else
953  {
954 
955  if (name=="char" || name == "char const")
956  {
957  out << name << "* address:" << ((void *)input) << " points_to_value:"<< input ;
958  }
959  else
960  {
961  out << name << "* address:" << ((void *)input) << " points_to_value:"<< ValueAsString(*input);
962  }
963 
964  }
965  return out.str();
966  }
967 
968 inline string AsString()
969  {
970  return string("");
971  }
972 
973 // WriteFormatted do the work for LogLow, LogMed, LogHigh
974 
975 inline void WriteFormmatted(const char* format)
976  {
977  fprintf(LGDATA.LF,"%s",format);
978  }
979 
980 //template<typename T, typename... Args>
981 template<class T, class... Args>
982 static void WriteFormmatted(const char* format, T value, Args... args)
983  {
984  while (format && *format)
985  {
986  if (*format=='%' && *++format!='%')
987  {
988  if (*format == 'p')
989  {
990  fprintf(LGDATA.LF,"%p",GetAddress(value)); // log just the address
991  }
992  else if (*format == 'S')
993  {
994  fprintf(LGDATA.LF,"%s",AsString(value).c_str()); // show with the datatype name
995  }
996  else
997  {
998  fprintf(LGDATA.LF,"%s",ValueAsString(value).c_str()); // just the value
999  }
1000  {
1001  return WriteFormmatted(++format, args...); // ``peel off'' first argument
1002  }
1003  }
1004  fprintf(LGDATA.LF,"%c",*format++);
1005  }
1006  // if we are down here there are more variables passed in that corresponding place holders %P %S %s
1007  fprintf(LGDATA.LF,"\n\nextra arguments provided to Logger::Log you need a placeholder %%P or %%S or %%s for each additional parameter");
1008  }
1009 
1010 
1011 
1012 
1013 
1014 template <typename... Args>
1015 static void LoggerLow(const char * fn, int ln,const char* format, Args... args)
1016  {
1017 #if LOGLEVEL >2
1018  LoggerOpen();
1019  fprintf(LGDATA.LF,"%s%s at line %d :",LGDATA.INDENT_BUFFER,fn,ln);// indent
1020  WriteFormmatted(format, args...);
1021  LoggerClose();
1022 #endif
1023  }
1024 
1025 template <typename... Args>
1026 static void LoggerMed(const char * fn, int ln,const char* format, Args... args)
1027  {
1028 #if LOGLEVEL >1
1029  LoggerOpen();
1030  fprintf(LGDATA.LF,"%s%s at line %d :",LGDATA.INDENT_BUFFER,fn,ln);// indent
1031  WriteFormmatted(format, args...);
1032  LoggerClose();
1033 #endif
1034  }
1035 template <typename... Args>
1036 static void LoggerHigh(const char * fn, int ln, const char* format, Args... args)
1037  {
1038 #if LOGLEVEL >0
1039  LoggerOpen();
1040  fprintf(LGDATA.LF,"%s%s at line %d :",LGDATA.INDENT_BUFFER,fn,ln);// indent
1041  WriteFormmatted(format, args...);
1042  LoggerClose();
1043 #endif
1044  }
1045 
1046 
1047 template <typename T>
1048 void LoggerEndReturning(const char * fn,int ln,const T & val)
1049  {
1050  LoggerOpen();
1051  fprintf(LGDATA.LF,"%sEnd frame(%d)--%s at line %d\nReturn Value:%s",LGDATA.INDENT_BUFFER,LGDATA.Frame,fn,ln,ValueAsString(val).c_str());
1052  fprintf(LGDATA.LF,"\n\n");
1053  LoggerSetIndent(-2);
1054  LoggerClose();
1055  LGDATA.Frame--;
1056  }
1057 
1058 
1059 
1060 #endif // LOGLEVEL > 0
1061 
1062 
1063 
1064 
1065 
1066 
1067 
1068 
1069 
1070 
1071 /*********************************************************************************************************************
1072  **********************************************************************************************************************
1073 
1074  below are fucnctions that you wont be calling they are
1075  for use by other functions
1076 
1077 
1078  **********************************************************************************************************************
1079  **********************************************************************************************************************/
1080 
1081 template <typename CharT>
1082 std::streamsize ignore_line (
1083  std::basic_istream<CharT>& in, bool always_discard )
1084  {
1085  std::streamsize nread = 0;
1086  if ( always_discard
1087  || ( in.rdbuf()->sungetc() != std::char_traits<CharT>::eof()
1088  && in.get() != in.widen ( '\n' ) ) )
1089  {
1090  // The stream is good, and we haven't
1091  // read a full line yet, so clear it out
1092  in.ignore ( std::numeric_limits<std::streamsize>::max(), in.widen ( '\n' ) );
1093  nread = in.gcount();
1094  }
1095  return nread;
1096  }
1097 
1098