diff --git a/include/examples/DisconnectPacket.h b/include/examples/DisconnectPacket.h index c6a51bb..ae61f43 100644 --- a/include/examples/DisconnectPacket.h +++ b/include/examples/DisconnectPacket.h @@ -4,7 +4,9 @@ #include #include -enum DisconnectPacketFields { Reason = 0 }; +enum DisconnectPacketFields { + Reason = 0 +}; using DisconnectFields = std::tuple; diff --git a/include/sp/common/MacroMap.h b/include/sp/common/MacroMap.h deleted file mode 100644 index e5afacf..0000000 --- a/include/sp/common/MacroMap.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Created by William Swanson in 2012. - * - * I, William Swanson, dedicate this work to the public domain. - * I waive all rights to the work worldwide under copyright law, - * including all related and neighboring rights, - * to the extent allowed by law. - * - * You can copy, modify, distribute and perform the work, - * even for commercial purposes, all without asking permission. - */ - -#ifndef MAP_H_INCLUDED -#define MAP_H_INCLUDED - -#define EVAL0(...) __VA_ARGS__ -#define EVAL1(...) EVAL0(EVAL0(EVAL0(__VA_ARGS__))) -#define EVAL2(...) EVAL1(EVAL1(EVAL1(__VA_ARGS__))) -#define EVAL3(...) EVAL2(EVAL2(EVAL2(__VA_ARGS__))) -#define EVAL4(...) EVAL3(EVAL3(EVAL3(__VA_ARGS__))) -#define EVAL(...) EVAL4(EVAL4(EVAL4(__VA_ARGS__))) - -#define MAP_END(...) -#define MAP_OUT -#define MAP_COMMA , - -#define MAP_GET_END2() 0, MAP_END -#define MAP_GET_END1(...) MAP_GET_END2 -#define MAP_GET_END(...) MAP_GET_END1 -#define MAP_NEXT0(test, next, ...) next MAP_OUT -#define MAP_NEXT1(test, next) MAP_NEXT0(test, next, 0) -#define MAP_NEXT(test, next) MAP_NEXT1(MAP_GET_END test, next) - -#define MAP0(f, x, peek, ...) f(x) MAP_NEXT(peek, MAP1)(f, peek, __VA_ARGS__) -#define MAP1(f, x, peek, ...) f(x) MAP_NEXT(peek, MAP0)(f, peek, __VA_ARGS__) - -#define MAP_LIST_NEXT1(test, next) MAP_NEXT0(test, MAP_COMMA next, 0) -#define MAP_LIST_NEXT(test, next) MAP_LIST_NEXT1(MAP_GET_END test, next) - -#define MAP_LIST0(f, x, peek, ...) f(x) MAP_LIST_NEXT(peek, MAP_LIST1)(f, peek, __VA_ARGS__) -#define MAP_LIST1(f, x, peek, ...) f(x) MAP_LIST_NEXT(peek, MAP_LIST0)(f, peek, __VA_ARGS__) - -/** - * Applies the function macro `f` to each of the remaining parameters. - */ -#define MAP(f, ...) EVAL(MAP1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -/** - * Applies the function macro `f` to each of the remaining parameters and - * inserts commas between the results. - */ -#define MAP_LIST(f, ...) EVAL(MAP_LIST1(f, __VA_ARGS__, ()()(), ()()(), ()()(), 0)) - -#endif \ No newline at end of file diff --git a/include/sp/common/NonCopyable.h b/include/sp/common/NonCopyable.h deleted file mode 100644 index 85b155e..0000000 --- a/include/sp/common/NonCopyable.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -/** - * \file NonCopyable.h - * \brief File containing the sp::NonCopyable class - */ - -namespace sp { - -/** - * \class NonCopyable - * \brief Class used to make a class non copyable - * \note Inherit from this class privately to make a class non copyable - */ -class NonCopyable { - public: - NonCopyable(const NonCopyable&) = delete; - NonCopyable& operator=(const NonCopyable&) = delete; - - protected: - NonCopyable() {} - ~NonCopyable() {} -}; - -} // namespace sp diff --git a/include/sp/misc/Format.h b/include/sp/misc/Format.h deleted file mode 100644 index 55ba136..0000000 --- a/include/sp/misc/Format.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -/** - * \file Format.h - * \brief This file contains the definition of the `Format` function. - */ - -#include -#include -#include - -namespace sp { -namespace utils { - -/** - * \brief Formats a string using a format string and variadic arguments. - * - * This function takes a format string and a variable number of arguments and returns a formatted string. - * The format string can contain placeholders that will be replaced by the corresponding arguments. - * - * \param format The format string. - * \param args The variadic arguments to be formatted. - * \return The formatted string. - * \throws std::runtime_error if an error occurs during formatting. - */ -template -std::string Format(const std::string& format, Args... args) { - int size = snprintf(nullptr, 0, format.c_str(), args...) + 1; // Extra space for '\0' - if (size <= 0) { - throw std::runtime_error("Error during formatting."); - } - std::unique_ptr buf(new char[size]); - snprintf(buf.get(), static_cast(size), format.c_str(), args...); - return std::string(buf.get(), buf.get() + size - 1); // We don't want the '\0' inside -} - -} // namespace utils -} // namespace sp diff --git a/include/sp/misc/Log.h b/include/sp/misc/Log.h deleted file mode 100644 index 4e83c7d..0000000 --- a/include/sp/misc/Log.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -/** - * \file Log.h - * \brief File defining log functions - */ - -#include - -namespace sp { -namespace utils { - -/** - * \brief Logs a normal message. - * \param msg The message to be logged. - */ -void LOG(const std::string& msg); - -/** - * \brief Logs a normal message in debug mode. - * \param msg The message to be logged. - */ -void LOGD(const std::string& msg); - -/** - * \brief Logs an error message. - * \param err The error message to be logged. - */ -void LOGE(const std::string& err); - -} // namespace utils -} // namespace sp diff --git a/include/sp/misc/Test.h b/include/sp/misc/Test.h deleted file mode 100644 index da122c7..0000000 --- a/include/sp/misc/Test.h +++ /dev/null @@ -1,70 +0,0 @@ -#pragma once - -/** - * \file Test.h - * \brief File containing unit testing utilities - */ - -#include -#include - -namespace sp { -namespace test { - -/** - * \def SP_TEST_SUCCESSFUL - * \brief Used in tests to indicate that a test was successful - */ -#define SP_TEST_SUCCESSFUL 0 - -/** - * \def SP_TEST_FAILED - * \brief Used in tests to indicate that a test failed - */ -#define SP_TEST_FAILED 1 - -#ifndef __FUNCTION_NAME__ -#ifdef _WIN32 -#define __FUNCTION_NAME__ __FUNCTION__ -#else -#define __FUNCTION_NAME__ __PRETTY_FUNCTION__ -#endif -#endif - -/** - * \def blitz_test_assert - * \param ... The expression to evaluate - * \brief Evaluates the expression and exits the program if not valid. - * \note It works like a basic assert() but also in release mode - */ -#define sp_test_assert(...) \ - if (!static_cast(__VA_ARGS__)) { \ - td::test::LogAssert(#__VA_ARGS__, __FILE__, __LINE__, __FUNCTION_NAME__); \ - std::exit(SP_TEST_FAILED); \ - } - - -/** - * \def blitz_debug_assert - * \param ... The expression to execute - * \brief Assertion without checks in release mode - * \note The expression is always executed. However, in release, no checks are made ! - */ -#ifdef NDEBUG -#define sp_debug_assert(...) __VA_ARGS__ -#else -#define sp_debug_assert sp_test_assert -#endif - - -/** - * \brief Prints an error message associated with a failed assertion - * \param expression The expression that was tested - * \param file The file in which the assertion failed - * \param line The line in the file in which the assertion failed - * \param function The function in which the assertion failed - */ -void LogAssert(const char* expression, const char* file, int line, const char* function); - -} // namespace test -} // namespace sp diff --git a/include/sp/protocol/Message.h b/include/sp/protocol/Message.h index a83ca82..c347b24 100644 --- a/include/sp/protocol/Message.h +++ b/include/sp/protocol/Message.h @@ -3,7 +3,7 @@ // Inspired by // https://alex-robenko.gitbook.io/comms-protocols-cpp -#include +#include namespace sp { diff --git a/include/sp/protocol/MessageInterfaces.h b/include/sp/protocol/MessageInterfaces.h deleted file mode 100644 index bc15cb3..0000000 --- a/include/sp/protocol/MessageInterfaces.h +++ /dev/null @@ -1,278 +0,0 @@ -#pragma once - -#include -#include - -namespace sp { -namespace details { - -template -struct MessageInterfaceParsedOptions {}; - -template <> -struct MessageInterfaceParsedOptions<> { - static const bool HasMsgIdType = false; - static const bool HasLittleEndian = false; - static const bool HasReadOperations = false; - static const bool HasWriteOperations = false; - static const bool HasWriteId = false; - static const bool HasHandler = false; - static const bool HasValid = false; -}; - - - - - -template -struct MessageInterfaceParsedOptions, TOptions...> : public MessageInterfaceParsedOptions { - static const bool HasMsgIdType = true; - using MsgIdType = T; -}; - -template -struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { - static const bool HasLittleEndian = true; -}; - -template -struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { - static const bool HasReadOperations = true; -}; - -template -struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { - static const bool HasWriteOperations = true; -}; - -template -struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { - static const bool HasWriteId = true; -}; - -template -struct MessageInterfaceParsedOptions, TOptions...> : public MessageInterfaceParsedOptions { - static const bool HasHandler = true; - using HandlerType = option::Handler; -}; - -template -struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { - static const bool HasValid = true; -}; - - - - - -// ID retrieval chunk -template -class MessageInterfaceIdTypeBase : public TBase { - public: - using MsgIdType = TId; - MsgIdType GetId() const { - return GetIdImpl(); - } - - protected: - virtual MsgIdType GetIdImpl() const = 0; -}; - -// Big endian serialisation chunk -template -class MessageInterfaceBigEndian : public TBase { - protected: - template - void ReadData(T& value, DataBuffer& buffer) { - buffer >> value; - FromNetwork(value); - } - - template - void WriteData(T value, DataBuffer& buffer) { - ToNetwork(value); - buffer << value; - } -}; - -// Little endian serialisation chunk -template -class MessageInterfaceLittleEndian : public TBase { - protected: - template - void ReadData(T& value, DataBuffer& buffer) { - buffer >> value; - TrySwapBytes(value); - FromNetwork(value); - } - - template - void WriteData(const T& value, DataBuffer& buffer) { - ToNetwork(value); - TrySwapBytes(value); - buffer << value; - } -}; - -// Read functionality chunk -template -class MessageInterfaceReadBase : public TBase { - public: - void Read(DataBuffer& buffer) { - return ReadImpl(buffer); - } - - protected: - virtual void ReadImpl(DataBuffer& buffer) = 0; -}; - -// Write functionality chunk -template -class MessageInterfaceWriteBase : public TBase { - public: - void Write(DataBuffer& buffer) { - WriteImpl(buffer); - } - - protected: - virtual void WriteImpl(DataBuffer& buffer) = 0; -}; - -// Handler functionality chunk -template -class MessageInterfaceHandlerBase : public TBase { - public: - using HandlerType = typename THandler::HandlerT; - - void Dispatch(HandlerType& handler) { - DispatchImpl(handler); - } - - protected: - virtual void DispatchImpl(HandlerType& handler) = 0; -}; - -// Validity functionality chunk -template -class MessageInterfaceValidityBase : public TBase { - public: - bool Valid() const { - return ValidImpl(); - } - - protected: - virtual bool ValidImpl() const = 0; -}; - -// Writing id functionality chunk -template -class MessageInterfaceWriteIdBase : public TBase { - public: - void Write(DataBuffer& buffer) { - this->WriteData(this->GetId(), buffer); - this->WriteImpl(buffer); - } -}; - - - - -// Build message Id -template -struct MessageInterfaceProcessMsgId; - -template -struct MessageInterfaceProcessMsgId { - using Type = MessageInterfaceIdTypeBase; -}; - -template -struct MessageInterfaceProcessMsgId { - using Type = TBase; -}; - -// Build endianess -template -struct MessageInterfaceProcessEndian; - -template -struct MessageInterfaceProcessEndian { - using Type = MessageInterfaceLittleEndian; -}; - -template -struct MessageInterfaceProcessEndian { - using Type = MessageInterfaceBigEndian; -}; - -// Build read -template -struct MessageInterfaceProcessRead; - -template -struct MessageInterfaceProcessRead { - using Type = MessageInterfaceReadBase; -}; - -template -struct MessageInterfaceProcessRead { - using Type = TBase; -}; - -// Build write -template -struct MessageInterfaceProcessWrite; - -template -struct MessageInterfaceProcessWrite { - using Type = MessageInterfaceWriteBase; -}; - -template -struct MessageInterfaceProcessWrite { - using Type = TBase; -}; - -// Build handler -template -struct MessageInterfaceProcessHandler; - -template -struct MessageInterfaceProcessHandler { - using Type = MessageInterfaceHandlerBase; -}; - -template -struct MessageInterfaceProcessHandler { - using Type = TBase; -}; - -// Build valid -template -struct MessageInterfaceProcessValid; - -template -struct MessageInterfaceProcessValid { - using Type = MessageInterfaceValidityBase; -}; - -template -struct MessageInterfaceProcessValid { - using Type = TBase; -}; - -// Build id writing -template -struct MessageInterfaceProcessWriteId; - -template -struct MessageInterfaceProcessWriteId { - using Type = MessageInterfaceWriteIdBase; -}; - -template -struct MessageInterfaceProcessWriteId { - using Type = TBase; -}; -} // namespace details -} // namespace sp diff --git a/include/sp/protocol/MessageInterfaceBuilder.h b/include/sp/protocol/message/MessageInterfaceBuilder.h similarity index 96% rename from include/sp/protocol/MessageInterfaceBuilder.h rename to include/sp/protocol/message/MessageInterfaceBuilder.h index 4fb0b71..8c34bab 100644 --- a/include/sp/protocol/MessageInterfaceBuilder.h +++ b/include/sp/protocol/message/MessageInterfaceBuilder.h @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace sp { namespace details { diff --git a/include/sp/protocol/message/MessageInterfaceProcess.h b/include/sp/protocol/message/MessageInterfaceProcess.h new file mode 100644 index 0000000..b6d7da2 --- /dev/null +++ b/include/sp/protocol/message/MessageInterfaceProcess.h @@ -0,0 +1,105 @@ +#pragma once + +namespace sp { +namespace details { + +// Build message Id +template +struct MessageInterfaceProcessMsgId; + +template +struct MessageInterfaceProcessMsgId { + using Type = MessageInterfaceIdTypeBase; +}; + +template +struct MessageInterfaceProcessMsgId { + using Type = TBase; +}; + +// Build endianess +template +struct MessageInterfaceProcessEndian; + +template +struct MessageInterfaceProcessEndian { + using Type = MessageInterfaceLittleEndian; +}; + +template +struct MessageInterfaceProcessEndian { + using Type = MessageInterfaceBigEndian; +}; + +// Build read +template +struct MessageInterfaceProcessRead; + +template +struct MessageInterfaceProcessRead { + using Type = MessageInterfaceReadBase; +}; + +template +struct MessageInterfaceProcessRead { + using Type = TBase; +}; + +// Build write +template +struct MessageInterfaceProcessWrite; + +template +struct MessageInterfaceProcessWrite { + using Type = MessageInterfaceWriteBase; +}; + +template +struct MessageInterfaceProcessWrite { + using Type = TBase; +}; + +// Build handler +template +struct MessageInterfaceProcessHandler; + +template +struct MessageInterfaceProcessHandler { + using Type = MessageInterfaceHandlerBase; +}; + +template +struct MessageInterfaceProcessHandler { + using Type = TBase; +}; + +// Build valid +template +struct MessageInterfaceProcessValid; + +template +struct MessageInterfaceProcessValid { + using Type = MessageInterfaceValidityBase; +}; + +template +struct MessageInterfaceProcessValid { + using Type = TBase; +}; + +// Build id writing +template +struct MessageInterfaceProcessWriteId; + +template +struct MessageInterfaceProcessWriteId { + using Type = MessageInterfaceWriteIdBase; +}; + +template +struct MessageInterfaceProcessWriteId { + using Type = TBase; +}; + +} // namespace details +} // namespace sp \ No newline at end of file diff --git a/include/sp/protocol/message/MessageInterfaces.h b/include/sp/protocol/message/MessageInterfaces.h new file mode 100644 index 0000000..a1b1176 --- /dev/null +++ b/include/sp/protocol/message/MessageInterfaces.h @@ -0,0 +1,7 @@ +#pragma once + +#include + +#include +#include +#include diff --git a/include/sp/protocol/message/MessageInterfacesImpl.h b/include/sp/protocol/message/MessageInterfacesImpl.h new file mode 100644 index 0000000..9ccf3f9 --- /dev/null +++ b/include/sp/protocol/message/MessageInterfacesImpl.h @@ -0,0 +1,119 @@ +#pragma once + +#include + +namespace sp { +namespace details { + + +// ID retrieval chunk +template +class MessageInterfaceIdTypeBase : public TBase { + public: + using MsgIdType = TId; + MsgIdType GetId() const { + return GetIdImpl(); + } + + protected: + virtual MsgIdType GetIdImpl() const = 0; +}; + +// Big endian serialisation chunk +template +class MessageInterfaceBigEndian : public TBase { + protected: + template + void ReadData(T& value, DataBuffer& buffer) { + buffer >> value; + FromNetwork(value); + } + + template + void WriteData(T value, DataBuffer& buffer) { + ToNetwork(value); + buffer << value; + } +}; + +// Little endian serialisation chunk +template +class MessageInterfaceLittleEndian : public TBase { + protected: + template + void ReadData(T& value, DataBuffer& buffer) { + buffer >> value; + TrySwapBytes(value); + FromNetwork(value); + } + + template + void WriteData(const T& value, DataBuffer& buffer) { + ToNetwork(value); + TrySwapBytes(value); + buffer << value; + } +}; + +// Read functionality chunk +template +class MessageInterfaceReadBase : public TBase { + public: + void Read(DataBuffer& buffer) { + return ReadImpl(buffer); + } + + protected: + virtual void ReadImpl(DataBuffer& buffer) = 0; +}; + +// Write functionality chunk +template +class MessageInterfaceWriteBase : public TBase { + public: + void Write(DataBuffer& buffer) { + WriteImpl(buffer); + } + + protected: + virtual void WriteImpl(DataBuffer& buffer) = 0; +}; + +// Handler functionality chunk +template +class MessageInterfaceHandlerBase : public TBase { + public: + using HandlerType = typename THandler::HandlerT; + + void Dispatch(HandlerType& handler) { + DispatchImpl(handler); + } + + protected: + virtual void DispatchImpl(HandlerType& handler) = 0; +}; + +// Validity functionality chunk +template +class MessageInterfaceValidityBase : public TBase { + public: + bool Valid() const { + return ValidImpl(); + } + + protected: + virtual bool ValidImpl() const = 0; +}; + +// Writing id functionality chunk +template +class MessageInterfaceWriteIdBase : public TBase { + public: + void Write(DataBuffer& buffer) { + this->WriteData(this->GetId(), buffer); + this->WriteImpl(buffer); + } +}; + +} // namespace details +} // namespace sp diff --git a/include/sp/protocol/message/MessageInterfacesOptions.h b/include/sp/protocol/message/MessageInterfacesOptions.h new file mode 100644 index 0000000..15ecb06 --- /dev/null +++ b/include/sp/protocol/message/MessageInterfacesOptions.h @@ -0,0 +1,63 @@ +#pragma once + +namespace sp { +namespace details { + + +template +struct MessageInterfaceParsedOptions {}; + +template <> +struct MessageInterfaceParsedOptions<> { + static const bool HasMsgIdType = false; + static const bool HasLittleEndian = false; + static const bool HasReadOperations = false; + static const bool HasWriteOperations = false; + static const bool HasWriteId = false; + static const bool HasHandler = false; + static const bool HasValid = false; +}; + + + + + +template +struct MessageInterfaceParsedOptions, TOptions...> : public MessageInterfaceParsedOptions { + static const bool HasMsgIdType = true; + using MsgIdType = T; +}; + +template +struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { + static const bool HasLittleEndian = true; +}; + +template +struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { + static const bool HasReadOperations = true; +}; + +template +struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { + static const bool HasWriteOperations = true; +}; + +template +struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { + static const bool HasWriteId = true; +}; + +template +struct MessageInterfaceParsedOptions, TOptions...> : public MessageInterfaceParsedOptions { + static const bool HasHandler = true; + using HandlerType = option::Handler; +}; + +template +struct MessageInterfaceParsedOptions : public MessageInterfaceParsedOptions { + static const bool HasValid = true; +}; + +} // namespace details +} // namespace sp diff --git a/include/sp/protocol/Options.h b/include/sp/protocol/message/MessageOptions.h similarity index 100% rename from include/sp/protocol/Options.h rename to include/sp/protocol/message/MessageOptions.h diff --git a/src/sp/common/DataBuffer.cpp b/src/sp/common/DataBuffer.cpp index 42d424f..36975c5 100644 --- a/src/sp/common/DataBuffer.cpp +++ b/src/sp/common/DataBuffer.cpp @@ -4,9 +4,6 @@ #include #include -#include -#include - namespace sp { DataBuffer::DataBuffer() : m_ReadOffset(0) {} @@ -142,7 +139,7 @@ bool DataBuffer::ReadFile(const std::string& fileName) { m_Buffer = DataBuffer::Data(s.begin(), s.end()); m_ReadOffset = 0; } catch (std::exception& e) { - utils::LOGE(utils::Format("[IO] Failed to read file %s ! reason : %s", fileName.c_str(), e.what())); + // utils::LOGE(utils::Format("[IO] Failed to read file %s ! reason : %s", fileName.c_str(), e.what())); return false; } return m_Buffer.size() > 0; @@ -154,7 +151,7 @@ bool DataBuffer::WriteFile(const std::string& fileName) const { file.write(reinterpret_cast(m_Buffer.data()), static_cast(m_Buffer.size())); file.flush(); } catch (std::exception& e) { - utils::LOGE(utils::Format("[IO] Failed to read file %s ! reason : %s", fileName.c_str(), e.what())); + // utils::LOGE(utils::Format("[IO] Failed to read file %s ! reason : %s", fileName.c_str(), e.what())); return false; } return true; diff --git a/src/sp/misc/Log.cpp b/src/sp/misc/Log.cpp deleted file mode 100644 index 829f46d..0000000 --- a/src/sp/misc/Log.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include - - - -#ifdef SP_ANDROID_LOGGING -#include -#else -#include -#endif - -namespace sp { -namespace utils { - -void LOG(const std::string& msg) { -#ifdef SP_ANDROID_LOGGING - __android_log_print(ANDROID_LOG_INFO, "TRACKERS", "%s", msg.c_str()); -#else - std::cout << msg << "\n"; -#endif -} - -void LOGD(const std::string& msg) { -#if !defined(NDEBUG) - LOG(msg); -#endif -} - -void LOGE(const std::string& err) { -#ifdef SP_ANDROID_LOGGING - __android_log_print(ANDROID_LOG_ERROR, "TRACKERS", "%s", err.c_str()); -#else - std::cerr << err << "\n"; -#endif -} - -} // namespace utils -} // namespace sp diff --git a/src/sp/misc/Test.cpp b/src/sp/misc/Test.cpp deleted file mode 100644 index 28cb8ff..0000000 --- a/src/sp/misc/Test.cpp +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include - -namespace sp { -namespace test { - -void LogAssert(const char* expression, const char* file, int line, const char* function) { - utils::LOGE(utils::Format("%s:%i: %s: Assertion failed !", file, line, function)); - utils::LOGE(utils::Format(" %i |\t%s;", line, expression)); -} - -} // namespace test -} // namespace sp