::value, void>::type
-safeDelete(T*& pointer) {
- if (pointer == nullptr)
- return;
- delete pointer;
- pointer = nullptr;
-}
-/// @brief Bitwise operations for C++11 strong enum class. This casts e into Flag_T and returns value after bitwise operation
-/// Use these function as flag = bitwise::Or(MyEnum::val1, flag);
-namespace bitwise {
-template
-static inline base::type::EnumType And(Enum e, base::type::EnumType flag) {
- return static_cast(flag) & static_cast(e);
-}
-template
-static inline base::type::EnumType Not(Enum e, base::type::EnumType flag) {
- return static_cast(flag) & ~(static_cast(e));
-}
-template
-static inline base::type::EnumType Or(Enum e, base::type::EnumType flag) {
- return static_cast(flag) | static_cast(e);
-}
-} // namespace bitwise
-template
-static inline void addFlag(Enum e, base::type::EnumType* flag) {
- *flag = base::utils::bitwise::Or(e, *flag);
-}
-template
-static inline void removeFlag(Enum e, base::type::EnumType* flag) {
- *flag = base::utils::bitwise::Not(e, *flag);
-}
-template
-static inline bool hasFlag(Enum e, base::type::EnumType flag) {
- return base::utils::bitwise::And(e, flag) > 0x0;
-}
-} // namespace utils
-namespace threading {
-#if ELPP_THREADING_ENABLED
-# if !ELPP_USE_STD_THREADING
-namespace internal {
-/// @brief A mutex wrapper for compiler that dont yet support std::recursive_mutex
-class Mutex : base::NoCopy {
- public:
- Mutex(void) {
-# if ELPP_OS_UNIX
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
- pthread_mutex_init(&m_underlyingMutex, &attr);
- pthread_mutexattr_destroy(&attr);
-# elif ELPP_OS_WINDOWS
- InitializeCriticalSection(&m_underlyingMutex);
-# endif // ELPP_OS_UNIX
- }
-
- virtual ~Mutex(void) {
-# if ELPP_OS_UNIX
- pthread_mutex_destroy(&m_underlyingMutex);
-# elif ELPP_OS_WINDOWS
- DeleteCriticalSection(&m_underlyingMutex);
-# endif // ELPP_OS_UNIX
- }
-
- inline void lock(void) {
-# if ELPP_OS_UNIX
- pthread_mutex_lock(&m_underlyingMutex);
-# elif ELPP_OS_WINDOWS
- EnterCriticalSection(&m_underlyingMutex);
-# endif // ELPP_OS_UNIX
- }
-
- inline bool try_lock(void) {
-# if ELPP_OS_UNIX
- return (pthread_mutex_trylock(&m_underlyingMutex) == 0);
-# elif ELPP_OS_WINDOWS
- return TryEnterCriticalSection(&m_underlyingMutex);
-# endif // ELPP_OS_UNIX
- }
-
- inline void unlock(void) {
-# if ELPP_OS_UNIX
- pthread_mutex_unlock(&m_underlyingMutex);
-# elif ELPP_OS_WINDOWS
- LeaveCriticalSection(&m_underlyingMutex);
-# endif // ELPP_OS_UNIX
- }
-
- private:
-# if ELPP_OS_UNIX
- pthread_mutex_t m_underlyingMutex;
-# elif ELPP_OS_WINDOWS
- CRITICAL_SECTION m_underlyingMutex;
-# endif // ELPP_OS_UNIX
-};
-/// @brief Scoped lock for compiler that dont yet support std::lock_guard
-template
-class ScopedLock : base::NoCopy {
- public:
- explicit ScopedLock(M& mutex) {
- m_mutex = &mutex;
- m_mutex->lock();
- }
-
- virtual ~ScopedLock(void) {
- m_mutex->unlock();
- }
- private:
- M* m_mutex;
- ScopedLock(void);
-};
-} // namespace internal
-typedef base::threading::internal::Mutex Mutex;
-typedef base::threading::internal::ScopedLock ScopedLock;
-# else
-typedef std::recursive_mutex Mutex;
-typedef std::lock_guard ScopedLock;
-# endif // !ELPP_USE_STD_THREADING
-#else
-namespace internal {
-/// @brief Mutex wrapper used when multi-threading is disabled.
-class NoMutex : base::NoCopy {
- public:
- NoMutex(void) {}
- inline void lock(void) {}
- inline bool try_lock(void) {
- return true;
- }
- inline void unlock(void) {}
-};
-/// @brief Lock guard wrapper used when multi-threading is disabled.
-template
-class NoScopedLock : base::NoCopy {
- public:
- explicit NoScopedLock(Mutex&) {
- }
- virtual ~NoScopedLock(void) {
- }
- private:
- NoScopedLock(void);
-};
-} // namespace internal
-typedef base::threading::internal::NoMutex Mutex;
-typedef base::threading::internal::NoScopedLock ScopedLock;
-#endif // ELPP_THREADING_ENABLED
-/// @brief Base of thread safe class, this class is inheritable-only
-class ThreadSafe {
- public:
- virtual inline void acquireLock(void) ELPP_FINAL { m_mutex.lock(); }
- virtual inline void releaseLock(void) ELPP_FINAL { m_mutex.unlock(); }
- virtual inline base::threading::Mutex& lock(void) ELPP_FINAL { return m_mutex; }
- protected:
- ThreadSafe(void) {}
- virtual ~ThreadSafe(void) {}
- private:
- base::threading::Mutex m_mutex;
-};
-
-#if ELPP_THREADING_ENABLED
-# if !ELPP_USE_STD_THREADING
-/// @brief Gets ID of currently running threading in windows systems. On unix, nothing is returned.
-static std::string getCurrentThreadId(void) {
- std::stringstream ss;
-# if (ELPP_OS_WINDOWS)
- ss << GetCurrentThreadId();
-# endif // (ELPP_OS_WINDOWS)
- return ss.str();
-}
-# else
-/// @brief Gets ID of currently running threading using std::this_thread::get_id()
-static std::string getCurrentThreadId(void) {
- std::stringstream ss;
- ss << std::this_thread::get_id();
- return ss.str();
-}
-# endif // !ELPP_USE_STD_THREADING
-#else
-static inline std::string getCurrentThreadId(void) {
- return std::string();
-}
-#endif // ELPP_THREADING_ENABLED
-} // namespace threading
-namespace utils {
-class File : base::StaticClass {
- public:
- /// @brief Creates new out file stream for specified filename.
- /// @return Pointer to newly created fstream or nullptr
- static base::type::fstream_t* newFileStream(const std::string& filename);
-
- /// @brief Gets size of file provided in stream
- static std::size_t getSizeOfFile(base::type::fstream_t* fs);
-
- /// @brief Determines whether or not provided path exist in current file system
- static bool pathExists(const char* path, bool considerFile = false);
-
- /// @brief Creates specified path on file system
- /// @param path Path to create.
- static bool createPath(const std::string& path);
- /// @brief Extracts path of filename with leading slash
- static std::string extractPathFromFilename(const std::string& fullPath,
- const char* seperator = base::consts::kFilePathSeperator);
- /// @brief builds stripped filename and puts it in buff
- static void buildStrippedFilename(const char* filename, char buff[],
- std::size_t limit = base::consts::kSourceFilenameMaxLength);
- /// @brief builds base filename and puts it in buff
- static void buildBaseFilename(const std::string& fullPath, char buff[],
- std::size_t limit = base::consts::kSourceFilenameMaxLength,
- const char* seperator = base::consts::kFilePathSeperator);
-};
-/// @brief String utilities helper class used internally. You should not use it.
-class Str : base::StaticClass {
- public:
- /// @brief Checks if character is digit. Dont use libc implementation of it to prevent locale issues.
- static inline bool isDigit(char c) {
- return c >= '0' && c <= '9';
- }
-
- /// @brief Matches wildcards, '*' and '?' only supported.
- static bool wildCardMatch(const char* str, const char* pattern);
-
- static std::string& ltrim(std::string& str);
- static std::string& rtrim(std::string& str);
- static std::string& trim(std::string& str);
-
- /// @brief Determines whether or not str starts with specified string
- /// @param str String to check
- /// @param start String to check against
- /// @return Returns true if starts with specified string, false otherwise
- static bool startsWith(const std::string& str, const std::string& start);
-
- /// @brief Determines whether or not str ends with specified string
- /// @param str String to check
- /// @param end String to check against
- /// @return Returns true if ends with specified string, false otherwise
- static bool endsWith(const std::string& str, const std::string& end);
-
- /// @brief Replaces all instances of replaceWhat with 'replaceWith'. Original variable is changed for performance.
- /// @param [in,out] str String to replace from
- /// @param replaceWhat Character to replace
- /// @param replaceWith Character to replace with
- /// @return Modified version of str
- static std::string& replaceAll(std::string& str, char replaceWhat, char replaceWith);
-
- /// @brief Replaces all instances of 'replaceWhat' with 'replaceWith'. (String version) Replaces in place
- /// @param str String to replace from
- /// @param replaceWhat Character to replace
- /// @param replaceWith Character to replace with
- /// @return Modified (original) str
- static std::string& replaceAll(std::string& str, const std::string& replaceWhat,
- const std::string& replaceWith);
-
- static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat,
- const base::type::string_t& replaceWith);
-#if defined(ELPP_UNICODE)
- static void replaceFirstWithEscape(base::type::string_t& str, const base::type::string_t& replaceWhat,
- const std::string& replaceWith);
-#endif // defined(ELPP_UNICODE)
- /// @brief Converts string to uppercase
- /// @param str String to convert
- /// @return Uppercase string
- static std::string& toUpper(std::string& str);
-
- /// @brief Compares cstring equality - uses strcmp
- static bool cStringEq(const char* s1, const char* s2);
-
- /// @brief Compares cstring equality (case-insensitive) - uses toupper(char)
- /// Dont use strcasecmp because of CRT (VC++)
- static bool cStringCaseEq(const char* s1, const char* s2);
-
- /// @brief Returns true if c exist in str
- static bool contains(const char* str, char c);
-
- static char* convertAndAddToBuff(std::size_t n, int len, char* buf, const char* bufLim, bool zeroPadded = true);
- static char* addToBuff(const char* str, char* buf, const char* bufLim);
- static char* clearBuff(char buff[], std::size_t lim);
-
- /// @brief Converst wchar* to char*
- /// NOTE: Need to free return value after use!
- static char* wcharPtrToCharPtr(const wchar_t* line);
-};
-/// @brief Operating System helper static class used internally. You should not use it.
-class OS : base::StaticClass {
- public:
-#if ELPP_OS_WINDOWS
- /// @brief Gets environment variables for Windows based OS.
- /// We are not using getenv(const char*)
because of CRT deprecation
- /// @param varname Variable name to get environment variable value for
- /// @return If variable exist the value of it otherwise nullptr
- static const char* getWindowsEnvironmentVariable(const char* varname);
-#endif // ELPP_OS_WINDOWS
-#if ELPP_OS_ANDROID
- /// @brief Reads android property value
- static std::string getProperty(const char* prop);
-
- /// @brief Reads android device name
- static std::string getDeviceName(void);
-#endif // ELPP_OS_ANDROID
-
- /// @brief Runs command on terminal and returns the output.
- ///
- /// @detail This is applicable only on unix based systems, for all other OS, an empty string is returned.
- /// @param command Bash command
- /// @return Result of bash output or empty string if no result found.
- static const std::string getBashOutput(const char* command);
-
- /// @brief Gets environment variable. This is cross-platform and CRT safe (for VC++)
- /// @param variableName Environment variable name
- /// @param defaultVal If no environment variable or value found the value to return by default
- /// @param alternativeBashCommand If environment variable not found what would be alternative bash command
- /// in order to look for value user is looking for. E.g, for 'user' alternative command will 'whoami'
- static std::string getEnvironmentVariable(const char* variableName, const char* defaultVal,
- const char* alternativeBashCommand = nullptr);
- /// @brief Gets current username.
- static std::string currentUser(void);
-
- /// @brief Gets current host name or computer name.
- ///
- /// @detail For android systems this is device name with its manufacturer and model seperated by hyphen
- static std::string currentHost(void);
- /// @brief Whether or not terminal supports colors
- static bool termSupportsColor(void);
-};
-/// @brief Contains utilities for cross-platform date/time. This class make use of el::base::utils::Str
-class DateTime : base::StaticClass {
- public:
- /// @brief Cross platform gettimeofday for Windows and unix platform. This can be used to determine current microsecond.
- ///
- /// @detail For unix system it uses gettimeofday(timeval*, timezone*) and for Windows, a seperate implementation is provided
- /// @param [in,out] tv Pointer that gets updated
- static void gettimeofday(struct timeval* tv);
-
- /// @brief Gets current date and time with a subsecond part.
- /// @param format User provided date/time format
- /// @param ssPrec A pointer to base::SubsecondPrecision from configuration (non-null)
- /// @returns string based date time in specified format.
- static std::string getDateTime(const char* format, const base::SubsecondPrecision* ssPrec);
-
- /// @brief Converts timeval (struct from ctime) to string using specified format and subsecond precision
- static std::string timevalToString(struct timeval tval, const char* format,
- const el::base::SubsecondPrecision* ssPrec);
-
- /// @brief Formats time to get unit accordingly, units like second if > 1000 or minutes if > 60000 etc
- static base::type::string_t formatTime(unsigned long long time, base::TimestampUnit timestampUnit);
-
- /// @brief Gets time difference in milli/micro second depending on timestampUnit
- static unsigned long long getTimeDifference(const struct timeval& endTime, const struct timeval& startTime,
- base::TimestampUnit timestampUnit);
-
-
- static struct ::tm* buildTimeInfo(struct timeval* currTime, struct ::tm* timeInfo);
- private:
- static char* parseFormat(char* buf, std::size_t bufSz, const char* format, const struct tm* tInfo,
- std::size_t msec, const base::SubsecondPrecision* ssPrec);
-};
-/// @brief Command line arguments for application if specified using el::Helpers::setArgs(..) or START_EASYLOGGINGPP(..)
-class CommandLineArgs {
- public:
- CommandLineArgs(void) {
- setArgs(0, static_cast(nullptr));
- }
- CommandLineArgs(int argc, const char** argv) {
- setArgs(argc, argv);
- }
- CommandLineArgs(int argc, char** argv) {
- setArgs(argc, argv);
- }
- virtual ~CommandLineArgs(void) {}
- /// @brief Sets arguments and parses them
- inline void setArgs(int argc, const char** argv) {
- setArgs(argc, const_cast(argv));
- }
- /// @brief Sets arguments and parses them
- void setArgs(int argc, char** argv);
- /// @brief Returns true if arguments contain paramKey with a value (seperated by '=')
- bool hasParamWithValue(const char* paramKey) const;
- /// @brief Returns value of arguments
- /// @see hasParamWithValue(const char*)
- const char* getParamValue(const char* paramKey) const;
- /// @brief Return true if arguments has a param (not having a value) i,e without '='
- bool hasParam(const char* paramKey) const;
- /// @brief Returns true if no params available. This exclude argv[0]
- bool empty(void) const;
- /// @brief Returns total number of arguments. This exclude argv[0]
- std::size_t size(void) const;
- friend base::type::ostream_t& operator<<(base::type::ostream_t& os, const CommandLineArgs& c);
-
- private:
- int m_argc;
- char** m_argv;
- std::unordered_map m_paramsWithValue;
- std::vector m_params;
-};
-/// @brief Abstract registry (aka repository) that provides basic interface for pointer repository specified by T_Ptr type.
-///
-/// @detail Most of the functions are virtual final methods but anything implementing this abstract class should implement
-/// unregisterAll() and deepCopy(const AbstractRegistry&) and write registerNew() method according to container
-/// and few more methods; get() to find element, unregister() to unregister single entry.
-/// Please note that this is thread-unsafe and should also implement thread-safety mechanisms in implementation.
-template
-class AbstractRegistry : public base::threading::ThreadSafe {
- public:
- typedef typename Container::iterator iterator;
- typedef typename Container::const_iterator const_iterator;
-
- /// @brief Default constructor
- AbstractRegistry(void) {}
-
- /// @brief Move constructor that is useful for base classes
- AbstractRegistry(AbstractRegistry&& sr) {
- if (this == &sr) {
- return;
- }
- unregisterAll();
- m_list = std::move(sr.m_list);
- }
-
- bool operator==(const AbstractRegistry& other) {
- if (size() != other.size()) {
- return false;
- }
- for (std::size_t i = 0; i < m_list.size(); ++i) {
- if (m_list.at(i) != other.m_list.at(i)) {
- return false;
- }
- }
- return true;
- }
-
- bool operator!=(const AbstractRegistry& other) {
- if (size() != other.size()) {
- return true;
- }
- for (std::size_t i = 0; i < m_list.size(); ++i) {
- if (m_list.at(i) != other.m_list.at(i)) {
- return true;
- }
- }
- return false;
- }
-
- /// @brief Assignment move operator
- AbstractRegistry& operator=(AbstractRegistry&& sr) {
- if (this == &sr) {
- return *this;
- }
- unregisterAll();
- m_list = std::move(sr.m_list);
- return *this;
- }
-
- virtual ~AbstractRegistry(void) {
- }
-
- /// @return Iterator pointer from start of repository
- virtual inline iterator begin(void) ELPP_FINAL {
- return m_list.begin();
- }
-
- /// @return Iterator pointer from end of repository
- virtual inline iterator end(void) ELPP_FINAL {
- return m_list.end();
- }
-
-
- /// @return Constant iterator pointer from start of repository
- virtual inline const_iterator cbegin(void) const ELPP_FINAL {
- return m_list.cbegin();
- }
-
- /// @return End of repository
- virtual inline const_iterator cend(void) const ELPP_FINAL {
- return m_list.cend();
- }
-
- /// @return Whether or not repository is empty
- virtual inline bool empty(void) const ELPP_FINAL {
- return m_list.empty();
- }
-
- /// @return Size of repository
- virtual inline std::size_t size(void) const ELPP_FINAL {
- return m_list.size();
- }
-
- /// @brief Returns underlying container by reference
- virtual inline Container& list(void) ELPP_FINAL {
- return m_list;
- }
-
- /// @brief Returns underlying container by constant reference.
- virtual inline const Container& list(void) const ELPP_FINAL {
- return m_list;
- }
-
- /// @brief Unregisters all the pointers from current repository.
- virtual void unregisterAll(void) = 0;
-
- protected:
- virtual void deepCopy(const AbstractRegistry&) = 0;
- void reinitDeepCopy(const AbstractRegistry& sr) {
- unregisterAll();
- deepCopy(sr);
- }
-
- private:
- Container m_list;
-};
-
-/// @brief A pointer registry mechanism to manage memory and provide search functionalities. (non-predicate version)
-///
-/// @detail NOTE: This is thread-unsafe implementation (although it contains lock function, it does not use these functions)
-/// of AbstractRegistry. Any implementation of this class should be
-/// explicitly (by using lock functions)
-template
-class Registry : public AbstractRegistry> {
- public:
- typedef typename Registry::iterator iterator;
- typedef typename Registry