DynExp
Highly flexible laboratory automation for dynamically changing experiments.
Util.h
Go to the documentation of this file.
1 // This file is part of DynExp.
2 
8 #pragma once
9 
10 #include "Exception.h"
11 
16 namespace Util
17 {
23  {
24  protected:
25  constexpr INonCopyable() = default;
26  ~INonCopyable() = default;
27 
28  public:
29  INonCopyable(const INonCopyable&) = delete;
30  INonCopyable& operator=(const INonCopyable&) = delete;
31  };
32 
38  {
39  protected:
40  constexpr INonMovable() = default;
41  ~INonMovable() = default;
42 
43  public:
44  INonMovable(const INonMovable&) = default;
45  INonMovable& operator=(const INonMovable&) = default;
46 
47  INonMovable(INonMovable&&) = delete;
49  };
50 
55  class ILockable : public INonCopyable
56  {
57  public:
62  static constexpr std::chrono::milliseconds DefaultTimeout = std::chrono::milliseconds(10);
63 
64  protected:
65  using MutexType = std::timed_mutex;
66  using LockType = std::unique_lock<MutexType>;
67 
68  ILockable() = default;
69  ~ILockable() = default;
70 
79  [[nodiscard]] LockType AcquireLock(const std::chrono::milliseconds Timeout = DefaultTimeout) const;
80 
81  private:
82  mutable MutexType LockMutex;
83  };
84 
85  class TimeoutException;
86  template <typename> class SynchronizedPointer;
87 
93  {
94  // Every SynchronizedPointer<...> should be friend to allow SynchronizedPointers to derived classes
95  template <typename>
96  friend class SynchronizedPointer;
97 
98  protected:
101 
102  private:
111  void AcquireLock(const std::chrono::milliseconds Timeout) const
112  {
113  using namespace std::chrono_literals;
114 
115  // In order to compensate for spurious failures by retrying
116  // (see https://en.cppreference.com/w/cpp/thread/timed_mutex/try_lock_for)
117  constexpr int NumTries = 2;
118 
119  if (OwnerID != std::this_thread::get_id())
120  {
121  if (Timeout == 0ms)
122  LockMutex.lock();
123  else
124  {
125  bool Success = false;
126  auto TimeoutPerTry = Timeout / NumTries;
127  for (auto i = NumTries; i > 0 && !Success; --i)
128  Success = LockMutex.try_lock_for(TimeoutPerTry);
129 
130  if (!Success)
131  throw TimeoutException("Timeout occurred while trying to lock a mutex.");
132  }
133 
134  OwnerID = std::this_thread::get_id();
135  }
136 
137  ++OwnedCount;
138  }
139 
144  void ReleaseLock() const
145  {
146  if (!OwnedCount || OwnerID != std::this_thread::get_id())
147  return;
148 
149  --OwnedCount;
150  if (!OwnedCount)
151  {
152  OwnerID = std::thread::id();
153  LockMutex.unlock();
154  }
155  }
156 
157  mutable std::timed_mutex LockMutex;
158  mutable std::atomic<std::thread::id> OwnerID;
159  mutable std::atomic<size_t> OwnedCount;
160  };
161 
168  template <typename T>
170  {
171  template <typename>
172  friend class SynchronizedPointer;
173 
174  public:
178  SynchronizedPointer() noexcept : LockableObject(nullptr) {}
179 
188  SynchronizedPointer(T* const LockableObject,
189  const std::chrono::milliseconds Timeout = ILockable::DefaultTimeout)
190  : LockableObject(LockableObject) { if (LockableObject) LockableObject->AcquireLock(Timeout); }
191 
197  SynchronizedPointer(SynchronizedPointer&& Other) noexcept : LockableObject(Other.LockableObject) { Other.LockableObject = nullptr; }
198 
206  {
207  LockableObject = Other.LockableObject;
208  Other.LockableObject = nullptr;
209 
210  return *this;
211  }
212 
220  template <typename U>
222  {
223  if (!Other.LockableObject)
224  LockableObject = nullptr;
225  else
226  {
227  LockableObject = dynamic_cast<T*>(Other.LockableObject);
228  if (!LockableObject)
229  throw Util::TypeErrorException();
230 
231  Other.LockableObject = nullptr;
232  }
233  }
234 
235  ~SynchronizedPointer() { if (LockableObject) LockableObject->ReleaseLock(); }
236 
241  auto get() const noexcept { return LockableObject; }
242 
243  bool operator==(const T* rhs) const noexcept { return LockableObject == rhs; }
244  bool operator!=(const T* rhs) const noexcept { return LockableObject != rhs; }
245  bool operator==(const SynchronizedPointer& rhs) const noexcept { return LockableObject == rhs.get(); }
246  bool operator!=(const SynchronizedPointer& rhs) const noexcept { return LockableObject != rhs.get(); }
247  explicit operator bool() const noexcept { return LockableObject != nullptr; }
248 
249  auto operator->() const noexcept { return LockableObject; }
250  auto& operator*() const noexcept { return *LockableObject; }
251 
252  private:
257  };
258 
265  {
266  public:
267  OneToOneNotifier() : EventOccurred(false), SomeoneIsWaiting(false), MutexCanBeDestroyed(true) {}
268  ~OneToOneNotifier();
269 
279  bool Wait(const std::chrono::milliseconds Timeout = std::chrono::milliseconds(0));
280 
281  void Notify();
282  void Ignore();
283 
284  private:
287  std::atomic<bool> MutexCanBeDestroyed;
288 
289  std::mutex Mutex;
290  std::condition_variable ConditionVariable;
291  };
292 
296  template <typename T, typename... ListTs>
297  struct is_contained_in : std::disjunction<std::is_same<T, ListTs>...> {};
298 
302  template <typename T, typename... ListTs>
303  inline constexpr bool is_contained_in_v = is_contained_in<T, ListTs...>::value;
304 
311  template <typename CallableT>
313 
317  template <typename ReturnT, typename ObjectT, typename... ArgumentTs>
318  struct member_fn_ptr_traits<ReturnT (ObjectT::*)(ArgumentTs...) const>
319  {
320  using return_type = ReturnT;
321  using instance_type = ObjectT;
322  using argument_types = std::tuple<ArgumentTs...>;
323  };
324 
328  template <typename ReturnT, typename ObjectT, typename... ArgumentTs>
329  struct member_fn_ptr_traits<ReturnT(ObjectT::*)(ArgumentTs...) noexcept>
330  {
331  using return_type = ReturnT;
332  using instance_type = ObjectT;
333  using argument_types = std::tuple<ArgumentTs...>;
334  };
335 
339  template <typename ReturnT, typename ObjectT, typename... ArgumentTs>
340  struct member_fn_ptr_traits<ReturnT(ObjectT::*)(ArgumentTs...) const noexcept>
341  {
342  using return_type = ReturnT;
343  using instance_type = ObjectT;
344  using argument_types = std::tuple<ArgumentTs...>;
345  };
346 
350  template <typename ReturnT, typename ObjectT, typename... ArgumentTs>
351  struct member_fn_ptr_traits<ReturnT (ObjectT::*)(ArgumentTs...)>
352  {
353  using return_type = ReturnT;
354  using instance_type = ObjectT;
355  using argument_types = std::tuple<ArgumentTs...>;
356  };
357 
361  template <typename CallableT>
363 
367  template <typename CallableT>
369 
373  template <typename CallableT>
375 
379  template <typename TupleT>
381 
385  template <typename FirstElementT, typename... ElementTs>
386  struct remove_first_from_tuple<std::tuple<FirstElementT, ElementTs...>> { using type = std::tuple<ElementTs...>; };
387 
391  template <typename TupleT>
393 
394  // Index sequence manipulation to define a starting point
395 
401  template <size_t Offset, typename IndexSequence>
403 
407  template <size_t Offset, size_t... Indices>
408  struct OffsetIndexSequence<Offset, std::index_sequence<Indices...>>
409  {
413  using type = std::index_sequence<Indices + Offset...>;
414  };
415 
419  template <size_t Offset, typename IndexSequence>
421 
427  template <size_t From, size_t To>
429  {
430  using type = OffsetIndexSequence_t<From, std::make_index_sequence<To - From>>;
431  };
432 
436  template <size_t From, size_t To>
438 
446  template <typename ObjectT, typename CallableT>
448  {
450 
451  public:
459  constexpr CallableMemberWrapper(ObjectT& Object, const CallableT Callable, ArgumentTs DefaultArgs = {}) noexcept
460  : Object(Object), Callable(Callable), DefaultArgs(std::move(DefaultArgs)) {}
461 
469  template <typename... ArgTs>
470  auto operator()(ArgTs&& ...Args) const
471  {
472  return Invoke(RangeIndexSequence_t<sizeof...(ArgTs), std::tuple_size_v<ArgumentTs>>(), std::forward<ArgTs>(Args)...);
473  }
474 
475  private:
476  template <size_t... Indices, typename... ArgTs>
477  auto Invoke(std::integer_sequence<size_t, Indices...>, ArgTs&& ...Args) const
478  {
479  return (Object.*Callable)(std::forward<ArgTs>(Args)..., std::get<Indices>(DefaultArgs)...);
480  }
481 
482  ObjectT& Object;
483  const CallableT Callable;
485  };
486 
492  template <typename ObjectT, typename CallableT>
494  {
495  public:
503  template <typename... ArgTs>
504  OnDestruction(ObjectT& Object, const CallableT Callable, ArgTs&& ...Args)
505  : CallableWrapper(Object, std::move(Callable), { std::forward<ArgTs>(Args)... }) {}
506 
507  ~OnDestruction() { CallableWrapper(); }
508 
509  private:
511  };
512 
517  {
518  public:
519  using DataType = unsigned char[];
520 
521  private:
522  using DataPtrType = std::unique_ptr<DataType>;
523 
524  public:
525  BlobDataType() = default;
526  BlobDataType(const BlobDataType& Other);
527  BlobDataType(BlobDataType&& Other) noexcept;
528 
529  BlobDataType& operator=(const BlobDataType& Other);
530  BlobDataType& operator=(BlobDataType&& Other) noexcept;
531 
532  void Reserve(size_t Size);
533  void Assign(size_t Size, const DataType Data);
534  void Reset();
535  DataPtrType::element_type* Release() noexcept;
536  auto GetPtr() noexcept { return DataPtr.get(); }
537  auto Size() const noexcept { return DataSize; }
538 
539  private:
541  size_t DataSize = 0;
542  };
543 
549  {
550  public:
554  enum class Values { Unknown, False, True };
555 
556  constexpr OptionalBool() noexcept : Value(Values::Unknown) {}
557  constexpr OptionalBool(Values Value) noexcept : Value(Value) {}
558  constexpr OptionalBool(bool b) noexcept : Value(b ? Values::True : Values::False) {}
559  constexpr OptionalBool(const OptionalBool& Other) noexcept : Value(Other.Value) {}
560 
561  constexpr OptionalBool& operator=(Values Value) noexcept { this->Value = Value; return *this; }
562  constexpr OptionalBool& operator=(bool b) noexcept { Value = b ? Values::True : Values::False; return *this; }
563  constexpr OptionalBool& operator=(OptionalBool& Other) noexcept { Value = Other.Value; return *this; }
564 
565  constexpr bool operator==(Values Value) const noexcept { return this->Value == Value; }
566  constexpr bool operator!=(Values Value) const noexcept { return this->Value != Value; }
567 
568  constexpr operator bool() const noexcept { return Value == Values::True; }
569  constexpr Values Get() const noexcept { return Value; }
570 
571  private:
573  };
574 
579 
587  template <typename T>
588  std::ostream& operator<<(std::ostream& stream, const std::chrono::time_point<T>& TimePoint)
589  {
590  const auto ZonedTime = std::chrono::zoned_time(std::chrono::current_zone(), std::chrono::round<std::chrono::seconds>(TimePoint));
591  stream << std::format("{:%T %d.%m.%Y}", ZonedTime);
592 
593  return stream;
594  }
595 
603  template <typename T>
604  T StrToT(const std::string& String)
605  {
606  std::stringstream ss(String);
607  T Value;
608  ss >> Value;
609 
610  if (ss.fail())
611  throw InvalidDataException("String cannot be converted to " + std::string(typeid(T).name()) + ".");
612 
613  return Value;
614  }
615 
624  template <typename T>
625  std::string ToStr(const T& Value, int Precision = -1)
626  {
627  std::stringstream ss;
628 
629  if (Precision >= 0)
630  ss << std::fixed << std::setprecision(Precision);
631 
632  ss << Value;
633  return ss.str();
634  }
635 
642  template <typename T>
643  std::string ToStr(const std::chrono::time_point<T>& TimePoint)
644  {
645  std::stringstream ss;
646 
647  Util::operator<<(ss, TimePoint);
648  return ss.str();
649  }
650 
656  inline std::string ToStr(const char Value) { return ToStr(static_cast<int>(Value)); }
657 
661  inline std::string ToStr(const uint8_t Value) { return ToStr(static_cast<int>(Value)); }
662 
668  inline std::string ToStr(const QString& Str) { return Str.toStdString(); }
669 
683  template <typename ToT, typename FromT, std::enable_if_t<
684  std::is_integral_v<ToT> && std::is_integral_v<FromT> &&
685  std::is_same_v<std::remove_cv_t<ToT>, std::remove_cv_t<FromT>>, int> = 0
686  >
687  inline ToT NumToT(const FromT Value)
688  {
689  return Value;
690  }
691 
695  template <typename ToT, typename FromT, std::enable_if_t<
696  std::is_integral_v<ToT> && std::is_integral_v<FromT> &&
697  !std::is_same_v<std::remove_cv_t<ToT>, std::remove_cv_t<FromT>> &&
698  ((std::is_signed_v<ToT> && std::is_signed_v<FromT>) || (std::is_unsigned_v<ToT> && std::is_unsigned_v<FromT>)), int> = 0
699  >
700  ToT NumToT(const FromT Value)
701  {
702  if (Value < std::numeric_limits<ToT>::lowest() || Value > std::numeric_limits<ToT>::max())
703  throw OutOfRangeException("Cannot convert Value into destiny type since this would cause an underflow or an overflow.");
704 
705  return static_cast<ToT>(Value);
706  }
707 
711  template <typename ToT, typename FromT, std::enable_if_t<
712  std::is_integral_v<ToT> && std::is_integral_v<FromT> &&
713  !std::is_same_v<std::remove_cv_t<ToT>, std::remove_cv_t<FromT>> &&
714  std::is_signed_v<ToT> && std::is_unsigned_v<FromT>, int> = 0
715  >
716  ToT NumToT(const FromT Value)
717  {
718  if (Value > static_cast<std::make_unsigned_t<ToT>>(std::numeric_limits<ToT>::max()))
719  throw OverflowException("Cannot convert Value into destiny type since this would cause an overflow.");
720 
721  return static_cast<ToT>(Value);
722  }
723 
727  template <typename ToT, typename FromT, std::enable_if_t<
728  std::is_integral_v<ToT> && std::is_integral_v<FromT> &&
729  !std::is_same_v<std::remove_cv_t<ToT>, std::remove_cv_t<FromT>> &&
730  std::is_unsigned_v<ToT> && std::is_signed_v<FromT>, int> = 0
731  >
732  ToT NumToT(const FromT Value)
733  {
734  if (Value < 0)
735  throw UnderflowException("Cannot convert Value into destiny type since this would cause an underflow.");
736  if (static_cast<std::make_unsigned_t<FromT>>(Value) > std::numeric_limits<ToT>::max())
737  throw OverflowException("Cannot convert Value into destiny type since this would cause an overflow.");
738 
739  return static_cast<ToT>(Value);
740  }
741 
745  template <typename ToT, std::enable_if_t<
746  std::is_integral_v<ToT> &&
747  !std::is_same_v<std::remove_cv_t<ToT>, double>, int> = 0
748  >
749  ToT NumToT(const double Value)
750  {
751  const double RoundedValue = std::round(Value);
752 
753  if (RoundedValue < static_cast<double>(std::numeric_limits<ToT>::lowest()))
754  throw UnderflowException("Cannot convert Value into double since this would cause an underflow.");
755  if (RoundedValue > static_cast<double>(std::numeric_limits<ToT>::max()))
756  throw OverflowException("Cannot convert Value into double since this would cause an overflow.");
757 
758  return static_cast<ToT>(RoundedValue);
759  }
760 
761  using seconds = std::chrono::duration<double>;
762  using picoseconds = std::chrono::duration<double, std::pico>;
763 
770  template <typename T>
771  inline std::string ToUnitStr();
772 
776  template <>
777  inline std::string ToUnitStr<std::chrono::seconds>()
778  {
779  return "s";
780  }
781 
785  template <>
786  inline std::string ToUnitStr<std::chrono::milliseconds>()
787  {
788  return "ms";
789  }
790 
794  template <>
795  inline std::string ToUnitStr<std::chrono::microseconds>()
796  {
797  return "us";
798  }
799 
803  template <>
804  inline std::string ToUnitStr<std::chrono::nanoseconds>()
805  {
806  return "ns";
807  }
808 
812  template <>
813  inline std::string ToUnitStr<seconds>()
814  {
815  return "s";
816  }
817 
821  template <>
822  inline std::string ToUnitStr<picoseconds>()
823  {
824  return "ps";
825  }
827 
833  inline std::string TrimTrailingZeros(const std::string& Str) { return Str.substr(0, Str.find('\0')); }
834 
839  inline auto CurrentTimeAndDateString() { return ToStr(std::chrono::system_clock::now()); }
840 
846  inline auto FilenameFromPath(std::string Path) { return Path.substr(Path.find_last_of("\\") + 1, Path.length() - Path.find_last_of("\\") - 1); }
847 
853  inline auto RemoveExtFromPath(std::string Path) { return Path.substr(0, Path.find_last_of(".")); }
854 
858  struct VersionType
859  {
860  unsigned int Major{};
861  unsigned int Minor{};
862  unsigned int Patch{};
863  };
864 
871  std::strong_ordering operator<=>(const VersionType& lhs, const VersionType& rhs);
872 
879  VersionType VersionFromString(std::string_view Str);
880 
886  inline std::string ToStr(const VersionType& Version) { return ToStr(Version.Major) + "." + ToStr(Version.Minor) + "." + ToStr(Version.Patch); }
887 
897  template <typename... Ts>
898  std::vector<std::tuple<Ts...>> ParseCSV(const std::string& CSVData, const char Delimiter = ';', const size_t SkipLines = 0)
899  {
900  std::vector<std::tuple<Ts...>> ParsedLines;
901  std::istringstream CSVDataStream(CSVData);
902 
903  // Ignore header lines
904  for (auto i = SkipLines; i > 0; --i)
905  CSVDataStream.ignore(std::numeric_limits<std::streamsize>::max(), CSVDataStream.widen('\n'));
906 
907  // Function to parse one field from a single line
908  const auto GetValue = [Delimiter]<typename T>(std::istringstream& LineStream) {
909  std::string ValueStr;
910  std::getline(LineStream, ValueStr, Delimiter);
911  std::istringstream ValueStream(ValueStr);
912  ValueStream.exceptions(std::istringstream::failbit | std::istringstream::badbit);
913 
914  T Value;
915  ValueStream >> Value;
916 
917  return Value;
918  };
919 
920  // Loop through each line and fill ParsedLines with tuples of column data.
921  std::string Line;
922  while (std::getline(CSVDataStream, Line))
923  {
924  std::istringstream LineStream(Line);
925  LineStream.exceptions(std::istringstream::failbit | std::istringstream::badbit);
926 
927  // Braced initialization to ensure correct evaluation order (left to right). Refer to
928  // https://stackoverflow.com/questions/14056000/how-to-avoid-undefined-execution-order-for-the-constructors-when-using-stdmake
929  ParsedLines.push_back({ GetValue.template operator()<Ts>(LineStream)... });
930  }
931 
932  return ParsedLines;
933  }
934 
941  std::string ExceptionToStr(const std::exception_ptr ExceptionPtr);
942 
948  std::string ToLower(std::string_view Str);
949 
959  std::vector<std::complex<double>> FFT(const std::vector<std::complex<double>>& Data, bool InverseTransform = false);
960 
965  class Warning : public ILockable
966  {
967  public:
972  struct WarningData
973  {
977  WarningData() : ErrorCode(DynExpErrorCodes::NoError), Line(0) {}
978 
979  WarningData(std::string Description, const int ErrorCode = DynExpErrorCodes::GeneralError,
980  const std::source_location Location = std::source_location::current())
981  : Description(std::move(Description)), ErrorCode(ErrorCode),
982  Line(Location.line()), Function(Location.function_name()), File(Location.file_name()) {}
983  WarningData(std::string Description, const int ErrorCode = DynExpErrorCodes::GeneralError,
984  const size_t Line = 0, std::string Function = "", std::string File = "")
985  : Description(std::move(Description)), ErrorCode(ErrorCode),
986  Line(Line), Function(std::move(Function)), File(std::move(File)) {}
987 
988  explicit operator bool() const noexcept { return ErrorCode != DynExpErrorCodes::NoError; }
989 
990  const std::string Description;
991  const int ErrorCode;
992  const size_t Line;
993  const std::string Function;
994  const std::string File;
995  };
996 
1000  Warning() : Data(std::make_unique<WarningData>()) {}
1001 
1008  Warning(std::string Description, const int ErrorCode = DynExpErrorCodes::GeneralError,
1009  const std::source_location Location = std::source_location::current())
1010  : Data(std::make_unique<WarningData>(std::move(Description), ErrorCode, Location)) {}
1011 
1016  Warning(const Exception& e)
1017  : Data(std::make_unique<WarningData>(e.what(), e.ErrorCode, e.Line, e.Function, e.File)) {}
1018 
1023  Warning(Warning&& Other) noexcept;
1024 
1025  virtual ~Warning() = default;
1026 
1027  void Reset();
1028 
1029  Warning& operator=(const Exception& e);
1030  Warning& operator=(Warning&& Other) noexcept;
1031 
1032  WarningData Get() const;
1033 
1034  private:
1038  std::unique_ptr<WarningData> Data;
1039  };
1040 
1044  struct LogEntry
1045  {
1046  LogEntry(std::string Message, ErrorType Type, std::chrono::system_clock::time_point TimePoint)
1047  : Message(std::move(Message)), Type(Type), TimePoint(TimePoint) {}
1048 
1049  const std::string Message;
1050  const ErrorType Type;
1051  const std::chrono::system_clock::time_point TimePoint;
1052  };
1053 
1060  class EventLogger : public ILockable
1061  {
1062  public:
1067  EventLogger();
1068 
1073  EventLogger(std::string Filename) : EventLogger() { OpenLogFile(Filename); }
1074 
1078  ~EventLogger() { CloseLogFileUnsafe(); }
1079 
1086 
1096  void Log(const std::string& Message, const ErrorType Type = ErrorType::Info,
1097  const size_t Line = 0, const std::string& Function = "", const std::string& File = "", const int ErrorCode = 0
1098 #ifdef DYNEXP_HAS_STACKTRACE
1099  , const std::stacktrace& Trace = {}
1100 #endif // DYNEXP_HAS_STACKTRACE
1101  ) noexcept;
1102 
1107  void Log(const Exception& E) noexcept;
1108 
1113  void Log(const Warning& W) noexcept;
1115 
1126  static std::string FormatLog(const std::string& Message, const size_t Line = 0,
1127  const std::string& Function = "", const std::string& Filename = "", const int ErrorCode = 0, const bool PrefixMessage = true);
1128 
1141  static std::string FormatLogHTML(const std::string& Message, const ErrorType Type = ErrorType::Info,
1142  const size_t Line = 0, const std::string& Function = "", const std::string& Filename = "", const int ErrorCode = 0
1143 #ifdef DYNEXP_HAS_STACKTRACE
1144  , const std::stacktrace& Trace = {}
1145 #endif // DYNEXP_HAS_STACKTRACE
1146  );
1147 
1152  void OpenLogFile(std::string Filename);
1153 
1157  void CloseLogFile() { auto lock = AcquireLock(LogOperationTimeout); CloseLogFileUnsafe(); }
1158 
1163  bool IsOpen() const { auto lock = AcquireLock(LogOperationTimeout); return IsOpenUnsafe(); }
1164 
1169  std::string GetLogFilename() const { auto lock = AcquireLock(LogOperationTimeout); return Filename; }
1170 
1174  void ClearLog() { auto lock = AcquireLock(LogOperationTimeout); ClearLogUnsafe(); }
1175 
1182  std::vector<LogEntry> GetLog(size_t FirstElement = 0) const;
1183 
1188  auto GetLogSize() const { auto lock = AcquireLock(LogOperationTimeout); return LogEntries.size(); }
1189 
1190  private:
1196  bool IsOpenUnsafe() const { return LogFile.is_open(); }
1197  void CloseLogFileUnsafe();
1198  void ClearLogUnsafe() { LogEntries.clear(); }
1200 
1205  static constexpr auto LogOperationTimeout = std::chrono::milliseconds(100);
1206 
1207  std::ofstream LogFile;
1208  std::string Filename;
1209 
1210  std::vector<LogEntry> LogEntries;
1211  };
1212 
1219  EventLogger& EventLog();
1220 
1227  template <typename EnumType, std::enable_if_t<
1228  std::is_enum_v<EnumType>, int> = 0
1229  >
1231  {
1232  public:
1236  constexpr FeatureTester() noexcept = default;
1237 
1243  template <size_t N>
1244  FeatureTester(const std::array<EnumType, N>& Flags)
1245  {
1246  for (const auto Flag : Flags)
1247  Set(Flag);
1248  }
1249 
1256  template <size_t N>
1257  bool Test(const std::array<EnumType, N>& Flags) const
1258  {
1259  for (const auto Flag : Flags)
1260  {
1261  auto Result = Features.test(static_cast<size_t>(Flag));
1262 
1263  if (!Result)
1264  false;
1265  }
1266 
1267  return true;
1268  }
1269 
1275  bool Test(EnumType Flag) const { return Features.test(static_cast<size_t>(Flag)); }
1276 
1281  void Set(EnumType Flag) { Features.set(static_cast<size_t>(Flag)); }
1282 
1283  private:
1287  std::bitset<static_cast<size_t>(EnumType::NUM_ELEMENTS)> Features;
1288  };
1289 
1300  template <
1301  typename CallableT,
1302  std::enable_if_t<std::is_enum_v<return_of_t<CallableT>>, int> = 0
1303  >
1305  {
1306  public:
1308  using CallableType = CallableT;
1309 
1317  constexpr StateMachineState(StateEnumType State, CallableT StateFunction, const char* Description = "", const bool IsFinal = false) noexcept
1318  : State(State), StateFunction(StateFunction), Description(Description), Final(IsFinal)
1319  {}
1320 
1321  constexpr StateEnumType GetState() const noexcept { return State; }
1322  constexpr auto GetDescription() const noexcept { return Description; }
1323  constexpr bool IsFinal() const noexcept { return Final; }
1324 
1333  template <typename... ArgTs>
1334  StateEnumType Invoke(instance_of_t<CallableT>& Instance, ArgTs&&... Args) const
1335  {
1336  return (Instance.*StateFunction)(std::forward<ArgTs>(Args)...);
1337  }
1338 
1339  private:
1341  const std::decay_t<CallableT> StateFunction;
1342  const char* Description;
1343 
1348  const bool Final;
1349  };
1350 
1360  template <typename StateMachineStateT>
1362  {
1363  public:
1364  using StateType = StateMachineStateT;
1365  using StateEnumType = typename StateType::StateEnumType;
1366  using ReplacementListType = std::unordered_map<StateEnumType, StateEnumType>;
1367 
1371  StateMachineContext() = default;
1372 
1383  StateMachineContext(ReplacementListType&& ReplacementList, const char* Description = "",
1384  std::initializer_list<const StateMachineContext*> BaseContexts = {})
1385  : ReplacementList(std::move(ReplacementList)), Description(Description)
1386  {
1387  for (auto BaseContext : BaseContexts)
1388  if (BaseContext)
1389  this->ReplacementList.insert(BaseContext->ReplacementList.cbegin(), BaseContext->ReplacementList.cend());
1390  }
1391 
1396  constexpr auto GetDescription() const noexcept { return Description; }
1397 
1405  {
1406  auto AdaptedState = ReplacementList.find(State);
1407 
1408  return AdaptedState == ReplacementList.cend() ? State : AdaptedState->second;
1409  }
1410 
1411  private:
1417 
1418  const char* Description;
1419  };
1420 
1433  template <typename StateMachineStateT>
1435  {
1436  public:
1437  using StateType = StateMachineStateT;
1438  using StateEnumType = typename StateType::StateEnumType;
1440 
1449  template <typename... StateMachineStateTs>
1450  StateMachine(const StateType& InitialState, const StateMachineStateTs&... States)
1451  : StatesList{ { InitialState.GetState(), &InitialState }, { States.GetState(), &States }... },
1452  CurrentState(&InitialState), CurrentContext(nullptr)
1453  {}
1454 
1455  const StateType* GetCurrentState() const noexcept { return CurrentState; }
1456  const ContextType* GetContext() const noexcept { return CurrentContext; }
1457 
1464  {
1465  if (CurrentContext)
1466  CurrentState = StatesList.at(CurrentContext.load()->AdaptState(NewState));
1467  else
1468  CurrentState = StatesList.at(NewState);
1469  }
1470 
1475  void SetContext(const ContextType* NewContext) { CurrentContext = NewContext; }
1476 
1480  void ResetContext() { CurrentContext = nullptr; }
1481 
1491  template <typename... ArgTs>
1493  {
1494  if (!CurrentState)
1495  throw InvalidStateException("CurrentState must not be nullptr in order to be invoked.");
1496 
1497  if (CurrentState.load()->IsFinal())
1498  CurrentState.load()->Invoke(Instance, std::forward<ArgTs>(Args)...);
1499  else
1500  SetCurrentState(CurrentState.load()->Invoke(Instance, std::forward<ArgTs>(Args)...));
1501  }
1502 
1503  private:
1508  const std::unordered_map<StateEnumType, const StateType*> StatesList;
1509 
1515  std::atomic<const StateType*> CurrentState;
1516  std::atomic<const ContextType*> CurrentContext;
1518  };
1519 }
Provides exception type and error definitions used by DynExp.
Data type which manages a binary large object. The reserved memory is freed upon destruction.
Definition: Util.h:517
unsigned char[] DataType
Type of the buffer's data.
Definition: Util.h:519
std::unique_ptr< DataType > DataPtrType
Type of the underlying smart pointer managing the buffer.
Definition: Util.h:522
DataPtrType DataPtr
Pointer to the buffer.
Definition: Util.h:540
auto Size() const noexcept
Returns the size of the stored data in bytes.
Definition: Util.h:537
BlobDataType()=default
Constructs an empty object.
Wraps a member function of some object and stores its default arguments. Moving from CallableMemberWr...
Definition: Util.h:448
auto operator()(ArgTs &&...Args) const
Invokes the stored member function. If arguments are passed, they are are forwarded instead of the st...
Definition: Util.h:470
argument_of_t< CallableT > ArgumentTs
Definition: Util.h:449
constexpr CallableMemberWrapper(ObjectT &Object, const CallableT Callable, ArgumentTs DefaultArgs={}) noexcept
Constructs a CallableMemberWrapper instance.
Definition: Util.h:459
ObjectT & Object
Instance of class Callable belongs to. Callable is invoked on this instance.
Definition: Util.h:482
auto Invoke(std::integer_sequence< size_t, Indices... >, ArgTs &&...Args) const
Definition: Util.h:477
const ArgumentTs DefaultArgs
Default arguments to be passed when invoking operator() with less arguments Callable expects.
Definition: Util.h:484
const CallableT Callable
Pointer to class member function to be invoked.
Definition: Util.h:483
Logs events like errors and writes them immediately to a HTML file in a human-readable format....
Definition: Util.h:1061
bool IsOpenUnsafe() const
Definition: Util.h:1196
void CloseLogFile()
Closes the log file on disk and writes terminating HTML tags.
Definition: Util.h:1157
EventLogger(std::string Filename)
Constructs the event logger with opening a log file on disk.
Definition: Util.h:1073
std::string GetLogFilename() const
Determines the full file path to the currently openend log file.
Definition: Util.h:1169
auto GetLogSize() const
Determines the number of entries in the internal event log.
Definition: Util.h:1188
std::ofstream LogFile
Stream object to write to the log file on disk.
Definition: Util.h:1207
std::string Filename
Filename and path to the log file on disk.
Definition: Util.h:1208
~EventLogger()
Destructor closes the log file on disk.
Definition: Util.h:1078
void ClearLog()
Clears the internal event log.
Definition: Util.h:1174
std::vector< LogEntry > LogEntries
Internally stored log entries.
Definition: Util.h:1210
void ClearLogUnsafe()
Definition: Util.h:1198
bool IsOpen() const
Determines whether the log file has been openend on disk.
Definition: Util.h:1163
DynExp exceptions are derived from this class. It contains basic information about the cause of the e...
Definition: Exception.h:51
Holds a bitset containing flags to indicate which features a certain instrument/ module etc....
Definition: Util.h:1231
constexpr FeatureTester() noexcept=default
Constructs a FeatureTester instance with no flags set.
void Set(EnumType Flag)
Sets a flag.
Definition: Util.h:1281
bool Test(const std::array< EnumType, N > &Flags) const
Tests whether all of the flags passed as an array are set.
Definition: Util.h:1257
std::bitset< static_cast< size_t >EnumType::NUM_ELEMENTS)> Features
Bitset containing the flags and their states.
Definition: Util.h:1287
bool Test(EnumType Flag) const
Tests whether a single flag is set.
Definition: Util.h:1275
Interface to allow synchronizing the access to derived classes between different threads by providing...
Definition: Util.h:56
ILockable()=default
LockType AcquireLock(const std::chrono::milliseconds Timeout=DefaultTimeout) const
Locks the internal mutex. Blocks until the mutex is locked or until the timeout duration is exceeded.
Definition: Util.cpp:8
std::timed_mutex MutexType
Definition: Util.h:65
std::unique_lock< MutexType > LockType
Definition: Util.h:66
MutexType LockMutex
Internal mutex used for locking.
Definition: Util.h:82
static constexpr std::chrono::milliseconds DefaultTimeout
Duration which is used as a default timeout within all methods of this class if no different duration...
Definition: Util.h:62
~ILockable()=default
Interface to delete copy constructor and copy assignment operator and thus make derived classes non-c...
Definition: Util.h:23
constexpr INonCopyable()=default
INonCopyable & operator=(const INonCopyable &)=delete
~INonCopyable()=default
INonCopyable(const INonCopyable &)=delete
Interface to delete move constructor and move assignment operator and thus make derived classes non-m...
Definition: Util.h:38
INonMovable(const INonMovable &)=default
~INonMovable()=default
INonMovable(INonMovable &&)=delete
constexpr INonMovable()=default
INonMovable & operator=(const INonMovable &)=default
INonMovable & operator=(INonMovable &&)=delete
Interface to allow synchronizing the access to derived classes between different threads by making th...
Definition: Util.h:93
std::timed_mutex LockMutex
Internal mutex used for locking.
Definition: Util.h:157
void ReleaseLock() const
Releases the internal mutex. Does nothing if the mutex was not locked or if the calling thread is not...
Definition: Util.h:144
~ISynchronizedPointerLockable()
Object should never be destroyed before completely unlocked.
Definition: Util.h:100
std::atomic< size_t > OwnedCount
Counts the lock requests of the current owning thread.
Definition: Util.h:159
std::atomic< std::thread::id > OwnerID
ID of the thread which currently owns the internal mutex.
Definition: Util.h:158
void AcquireLock(const std::chrono::milliseconds Timeout) const
Locks the internal mutex. Blocks until the mutex is locked or until the timeout duration is exceeded....
Definition: Util.h:111
Data to operate on is invalid for a specific purpose. This indicates a corrupted data structure or fu...
Definition: Exception.h:163
An operation cannot be performed currently since the related object is in an invalid state like an er...
Definition: Exception.h:150
Holds a CallableMemberWrapper and invokes its callable when being destroyed.
Definition: Util.h:494
CallableMemberWrapper< ObjectT, CallableT > CallableWrapper
Definition: Util.h:510
OnDestruction(ObjectT &Object, const CallableT Callable, ArgTs &&...Args)
Constructs a OnDestruction instance which calls Callable upon destruction of this instance.
Definition: Util.h:504
Helper class to communicate flags between different threads based on a condition variable and a mutex...
Definition: Util.h:265
std::condition_variable ConditionVariable
Definition: Util.h:290
std::atomic< bool > MutexCanBeDestroyed
Definition: Util.h:287
std::mutex Mutex
Definition: Util.h:289
Data type which stores an optional bool value (unknown, false, true). The type evaluates to bool whil...
Definition: Util.h:549
Values
Possible values. Values::Unknown evaluates to false.
Definition: Util.h:554
constexpr OptionalBool(bool b) noexcept
Contructs an instance holding b.
Definition: Util.h:558
constexpr OptionalBool(const OptionalBool &Other) noexcept
Contructs a copy of Other.
Definition: Util.h:559
constexpr OptionalBool(Values Value) noexcept
Contructs an instance holding Value.
Definition: Util.h:557
constexpr bool operator!=(Values Value) const noexcept
Returns false when Value matches stored value, true otherwise.
Definition: Util.h:566
constexpr bool operator==(Values Value) const noexcept
Returns true when Value matches stored value, false otherwise.
Definition: Util.h:565
constexpr OptionalBool & operator=(OptionalBool &Other) noexcept
Assigns value of Other, returns reference to this.
Definition: Util.h:563
constexpr OptionalBool() noexcept
Contructs an instance holding Values::Unknown.
Definition: Util.h:556
constexpr OptionalBool & operator=(Values Value) noexcept
Assigns Value, returns reference to this.
Definition: Util.h:561
constexpr OptionalBool & operator=(bool b) noexcept
Assigns b, returns reference to this.
Definition: Util.h:562
Values Value
Internal value.
Definition: Util.h:572
constexpr Values Get() const noexcept
Returns internal value.
Definition: Util.h:569
Thrown when a numeric operation would result in an overflow (e.g. due to incompatible data types)
Definition: Exception.h:199
State machine context as used by class StateMachine. A state machine context holds a map with keys an...
Definition: Util.h:1362
typename StateType::StateEnumType StateEnumType
Refer to class StateMachineState.
Definition: Util.h:1365
StateEnumType AdaptState(StateEnumType State) const
Checks whether the context contains a replacement entry for the state identified by State and returns...
Definition: Util.h:1404
const char * Description
Definition: Util.h:1418
std::unordered_map< StateEnumType, StateEnumType > ReplacementListType
Definition: Util.h:1366
constexpr auto GetDescription() const noexcept
Returns the context's description.
Definition: Util.h:1396
StateMachineStateT StateType
Definition: Util.h:1364
ReplacementListType ReplacementList
Within this context, the map's key states are replaced by the corresponding value states....
Definition: Util.h:1416
StateMachineContext()=default
Default constructor constructs an empty context not performing any state replacement.
StateMachineContext(ReplacementListType &&ReplacementList, const char *Description="", std::initializer_list< const StateMachineContext * > BaseContexts={})
Constructs a StateMachineContext from a replacement list appending the replacement lists of each cont...
Definition: Util.h:1383
State machine state as used by class StateMachine. A state mainly wraps a state function of the membe...
Definition: Util.h:1305
const StateEnumType State
Definition: Util.h:1340
CallableT CallableType
Definition: Util.h:1308
const char * Description
Definition: Util.h:1342
StateEnumType Invoke(instance_of_t< CallableT > &Instance, ArgTs &&... Args) const
Invokes the state function associated with this state on an instance of the class the state function ...
Definition: Util.h:1334
const bool Final
For final states, it is ensured that the state's state function can delete the state machine....
Definition: Util.h:1348
return_of_t< CallableT > StateEnumType
Definition: Util.h:1307
constexpr StateEnumType GetState() const noexcept
Returns the state's unique identifier.
Definition: Util.h:1321
const std::decay_t< CallableT > StateFunction
Definition: Util.h:1341
constexpr auto GetDescription() const noexcept
Returns the state's description.
Definition: Util.h:1322
constexpr StateMachineState(StateEnumType State, CallableT StateFunction, const char *Description="", const bool IsFinal=false) noexcept
Constructs a state machine state and assigns fixed parameters to it.
Definition: Util.h:1317
constexpr bool IsFinal() const noexcept
Returns whether this is a final state.
Definition: Util.h:1323
This class models a state machine. It keeps track of the current state and allows to invoke its assoc...
Definition: Util.h:1435
std::atomic< const StateType * > CurrentState
Definition: Util.h:1515
void Invoke(instance_of_t< typename StateType::CallableType > &Instance, ArgTs &&... Args)
Invokes the state function associated with the current state machine state on an instance of the clas...
Definition: Util.h:1492
void SetContext(const ContextType *NewContext)
Sets the current state machine context.
Definition: Util.h:1475
StateMachineStateT StateType
Definition: Util.h:1437
void ResetContext()
Removes the current state machine context.
Definition: Util.h:1480
void SetCurrentState(StateEnumType NewState)
Sets the current state as identified by an element from StateEnumType.
Definition: Util.h:1463
StateMachine(const StateType &InitialState, const StateMachineStateTs &... States)
Constructs a state machine assigning possible states to it. Automatically also adds InitialState,...
Definition: Util.h:1450
typename StateType::StateEnumType StateEnumType
Refer to class StateMachineState.
Definition: Util.h:1438
std::atomic< const ContextType * > CurrentContext
Definition: Util.h:1516
const std::unordered_map< StateEnumType, const StateType * > StatesList
Map of possible states. All states are uniquely identified by an element from StateEnumType....
Definition: Util.h:1508
const ContextType * GetContext() const noexcept
Returns a pointer to the current context.
Definition: Util.h:1456
const StateType * GetCurrentState() const noexcept
Returns a pointer to the current state.
Definition: Util.h:1455
Pointer to lock a class derived from ISynchronizedPointerLockable for synchronizing between threads....
Definition: Util.h:170
auto & operator*() const noexcept
Definition: Util.h:250
bool operator!=(const T *rhs) const noexcept
Definition: Util.h:244
SynchronizedPointer(SynchronizedPointer< U > &&Other)
Moves the LockableObject from a SynchronizedPointer<U> of another type U to a new instance of Synchro...
Definition: Util.h:221
SynchronizedPointer(T *const LockableObject, const std::chrono::milliseconds Timeout=ILockable::DefaultTimeout)
Constructs a pointer locking LockableObject. Blocks until LockableObject's mutex is locked or until t...
Definition: Util.h:188
bool operator==(const SynchronizedPointer &rhs) const noexcept
Definition: Util.h:245
SynchronizedPointer() noexcept
Contructs an instance with an empty pointer.
Definition: Util.h:178
SynchronizedPointer & operator=(SynchronizedPointer &&Other) noexcept
Move-assigns the LockableObject from another SynchronizedPointer instance Other to this instance....
Definition: Util.h:205
SynchronizedPointer(SynchronizedPointer &&Other) noexcept
Moves the LockableObject from another SynchronizedPointer instance Other to a new instance....
Definition: Util.h:197
auto operator->() const noexcept
Definition: Util.h:249
bool operator!=(const SynchronizedPointer &rhs) const noexcept
Definition: Util.h:246
T * LockableObject
Pointer to the locakable object managed by this class.
Definition: Util.h:256
auto get() const noexcept
Returns the managed (locked) object.
Definition: Util.h:241
bool operator==(const T *rhs) const noexcept
Definition: Util.h:243
Thrown when an operation timed out before it could be completed, especially used for locking shared d...
Definition: Exception.h:261
Thrown when an attempt was made to convert two incompatible types into each other.
Definition: Exception.h:248
Thrown when a numeric operation would result in an underflow (e.g. due to incompatible data types)
Definition: Exception.h:187
Class to store information about warnings in a thread-safe manner (deriving from ILockable)....
Definition: Util.h:966
Warning()
Constructs an empty Warning.
Definition: Util.h:1000
virtual ~Warning()=default
Warning(std::string Description, const int ErrorCode=DynExpErrorCodes::GeneralError, const std::source_location Location=std::source_location::current())
Constructs a Warning from specified information.
Definition: Util.h:1008
Warning(const Exception &e)
Constructs a Warning retrieving the warning data from an exception e.
Definition: Util.h:1016
std::unique_ptr< WarningData > Data
Pointer to warning data. Must never be nullptr.
Definition: Util.h:1038
DynExpErrorCodes
DynExp's error codes
Definition: Exception.h:22
DynExp's Util namespace contains commonly used functions and templates as well as extensions to Qt an...
Definition: circularbuf.cpp:7
std::string ToStr(const T &Value, int Precision=-1)
Converts a (numeric) value of type T to a std::string using operator<< of std::stringstream.
Definition: Util.h:625
typename member_fn_ptr_traits< CallableT >::instance_type instance_of_t
Alias for the class type a member function callable of type CallableT is member of.
Definition: Util.h:368
constexpr bool is_contained_in_v
Value type of is_contained_in.
Definition: Util.h:303
std::index_sequence< Indices+Offset... > type
Alias for offset index sequence.
Definition: Util.h:413
auto FilenameFromPath(std::string Path)
Extracts the filename from a path.
Definition: Util.h:846
std::string ExceptionToStr(const std::exception_ptr ExceptionPtr)
Returns the what() information of an exception derived from std::exception and stored in an exception...
Definition: Util.cpp:189
T StrToT(const std::string &String)
Converts a std::string to a value of type T using operator<< of std::stringstream.
Definition: Util.h:604
std::vector< std::tuple< Ts... > > ParseCSV(const std::string &CSVData, const char Delimiter=';', const size_t SkipLines=0)
Parses a string containing comma-separated values (csv) and inserts each row as one tuple containing ...
Definition: Util.h:898
std::string ToUnitStr< picoseconds >()
Returns a string describing the physical unit associated with type T. For example,...
Definition: Util.h:822
auto CurrentTimeAndDateString()
Returns a human-readable string describing the current time and date in the current time zone.
Definition: Util.h:839
typename remove_first_from_tuple< TupleT >::type remove_first_from_tuple_t
Alias for a tuple of types where the first type of the input tuple TupleT is removed.
Definition: Util.h:392
VersionType VersionFromString(std::string_view Str)
Extracts a program version from a string.
Definition: Util.cpp:162
unsigned int Major
Definition: Util.h:860
typename OffsetIndexSequence< Offset, IndexSequence >::type OffsetIndexSequence_t
Alias for type contained in OffsetIndexSequence.
Definition: Util.h:420
EventLogger & EventLog()
This function holds a static EventLogger instance and returns a reference to it. DynExp uses only one...
Definition: Util.cpp:509
typename member_fn_ptr_traits< CallableT >::return_type return_of_t
Alias for the return type of a member function callable of type CallableT.
Definition: Util.h:362
std::string ToUnitStr()
Returns a string describing the physical unit associated with type T. For example,...
unsigned int Minor
Definition: Util.h:861
std::chrono::duration< double, std::pico > picoseconds
Extends std::chrono by a duration data type for picoseconds.
Definition: Util.h:762
std::strong_ordering operator<=>(const VersionType &lhs, const VersionType &rhs)
Compares two program version types with each other.
Definition: Util.cpp:149
std::vector< std::complex< double > > FFT(const std::vector< std::complex< double >> &Data, bool InverseTransform)
Computes the Fast Fourier Transform (FFT) a vector of complex values.
Definition: Util.cpp:220
std::string ToLower(std::string_view Str)
Transforms a string into lower case.
Definition: Util.cpp:208
std::chrono::duration< double > seconds
Extends std::chrono by a duration data type for seconds capable of storing fractions of seconds.
Definition: Util.h:761
auto RemoveExtFromPath(std::string Path)
Removes the filename's extension from a path.
Definition: Util.h:853
std::string TrimTrailingZeros(const std::string &Str)
Removes trailing zeros ('\0') from a string.
Definition: Util.h:833
typename RangeIndexSequence< From, To >::type RangeIndexSequence_t
Alias for type contained in RangeIndexSequence.
Definition: Util.h:437
ToT NumToT(const FromT Value)
Converts a value of a numeric type to a value of another numeric type checking the conversion for its...
Definition: Util.h:687
std::ostream & operator<<(std::ostream &stream, const Exception &e)
Writes a DynExp exception in a user-readable way to a stream.
Definition: Exception.cpp:17
unsigned int Patch
Definition: Util.h:862
ErrorType
DynExp's error types
Definition: Exception.h:15
typename member_fn_ptr_traits< CallableT >::argument_types argument_of_t
Alias for a tuple of argument types the member function callable of type CallableT expects.
Definition: Util.h:374
std::string ToUnitStr< seconds >()
Returns a string describing the physical unit associated with type T. For example,...
Definition: Util.h:813
OffsetIndexSequence_t< From, std::make_index_sequence< To - From > > type
Definition: Util.h:430
Holds an alias for a std::index_sequence where all indices are shifted by an offset.
Definition: Util.h:402
Holds an alias for a std::index_sequence spanning a certain range.
Definition: Util.h:429
Data type describing DynExp's program version in the form Major.Minor.Patch.
Definition: Util.h:859
Extracts the return value type, the class type the callable is member of, and the argument types of a...
Definition: Util.h:312
Removes first type from a tuple of types TupleT.
Definition: Util.h:380
#define DYNEXP_HAS_STACKTRACE
Definition: stdafx.h:60
Data type of a single entry in DynExp's log.
Definition: Util.h:1045
LogEntry(std::string Message, ErrorType Type, std::chrono::system_clock::time_point TimePoint)
Definition: Util.h:1046
const std::string Message
String describing the log entry including reasons and consequences of the message.
Definition: Util.h:1049
const ErrorType Type
DynExp error code from DynExpErrorCodes::DynExpErrorCodes associated with the log enty
Definition: Util.h:1050
const std::chrono::system_clock::time_point TimePoint
Time point associated with the log enty.
Definition: Util.h:1051
Data associated with a warning. The class is convertible to bool (true if it describes an error/warni...
Definition: Util.h:973
const std::string Function
Function in source code where the warning occurred.
Definition: Util.h:993
const std::string Description
String describing the reason and consequences of the warning.
Definition: Util.h:990
const std::string File
Source code file where the warning occurred.
Definition: Util.h:994
const size_t Line
Line in source code where the warning occurred.
Definition: Util.h:992
WarningData(std::string Description, const int ErrorCode=DynExpErrorCodes::GeneralError, const size_t Line=0, std::string Function="", std::string File="")
Definition: Util.h:983
WarningData()
Default constructor sets ErrorCode to a non-error code.
Definition: Util.h:977
const int ErrorCode
DynExp error code from DynExpErrorCodes::DynExpErrorCodes
Definition: Util.h:991
WarningData(std::string Description, const int ErrorCode=DynExpErrorCodes::GeneralError, const std::source_location Location=std::source_location::current())
Definition: Util.h:979
Checks whether a type T is contained in a template parameter pack of types ListTs.
Definition: Util.h:297