diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt new file mode 100644 index 0000000..dba5784 --- /dev/null +++ b/cpp/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.15) +project(Platform.Exceptions) +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +add_library(${PROJECT_NAME}.Library INTERFACE) +target_include_directories(${PROJECT_NAME}.Library INTERFACE ${PROJECT_NAME}) +target_link_libraries(${PROJECT_NAME}.Library INTERFACE CONAN_PKG::platform.delegates) + +add_executable(${PROJECT_NAME}.Tests ${PROJECT_NAME}.Tests/AllTests.cpp) +target_link_libraries(${PROJECT_NAME}.Tests PRIVATE ${PROJECT_NAME}.Library) +target_link_libraries(${PROJECT_NAME}.Tests PRIVATE CONAN_PKG::gtest) +set_target_properties(${PROJECT_NAME}.Tests PROPERTIES CXX_STANDARD 20) diff --git a/cpp/Platform.Exceptions.Tests/AllTests.cpp b/cpp/Platform.Exceptions.Tests/AllTests.cpp index dd04d89..ca3504f 100644 --- a/cpp/Platform.Exceptions.Tests/AllTests.cpp +++ b/cpp/Platform.Exceptions.Tests/AllTests.cpp @@ -1,7 +1,6 @@ -#include "pch.h" -#include "CppUnitTest.h" -using namespace Microsoft::VisualStudio::CppUnitTestFramework; +#include "pch.h" // linux-like +#include + #include "EnsuranceTests.cpp" -// Due to the nature of extension methods these tests do not apply to C++ -//#include "Ignore/EnsureExtensions.cpp" -//#include "Ignore/IgnoredEnsuranceTests.cpp" +#include "Ignore/EnsureExtensions.cpp" +#include "Ignore/IgnoredEnsuranceTests.cpp" \ No newline at end of file diff --git a/cpp/Platform.Exceptions.Tests/EnsuranceTests.cpp b/cpp/Platform.Exceptions.Tests/EnsuranceTests.cpp index 6afcefc..1e96a4a 100644 --- a/cpp/Platform.Exceptions.Tests/EnsuranceTests.cpp +++ b/cpp/Platform.Exceptions.Tests/EnsuranceTests.cpp @@ -1,10 +1,7 @@ namespace Platform::Exceptions::Tests { - TEST_CLASS(EnsuranceTests) + TEST(EnsuranceTests, ArgumentNotNullEnsuranceTest) { - public: TEST_METHOD(ArgumentNotNullEnsuranceTest) - { - Assert::ExpectException([&]()-> auto { return Platform::Exceptions::EnsureExtensions::ArgumentNotNull(Platform::Exceptions::Ensure::Always, {}, "object"); }); - } + EXPECT_THROW(Always::ArgumentNotNull(nullptr, "object"), std::invalid_argument); }; } diff --git a/cpp/Platform.Exceptions.Tests/EnsureExtensions.cpp b/cpp/Platform.Exceptions.Tests/EnsureExtensions.cpp deleted file mode 100644 index d0b7619..0000000 --- a/cpp/Platform.Exceptions.Tests/EnsureExtensions.cpp +++ /dev/null @@ -1,9 +0,0 @@ -namespace Platform::Exceptions::Tests::Ignore -{ - class EnsureExtensions - { - public: template static void ArgumentNotNull(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, TArgument* argument, const char* argumentName) - { - } - }; -} diff --git a/cpp/Platform.Exceptions.Tests/Ignore/EnsureExtensions.cpp b/cpp/Platform.Exceptions.Tests/Ignore/EnsureExtensions.cpp index 4b16d62..694f2ec 100644 --- a/cpp/Platform.Exceptions.Tests/Ignore/EnsureExtensions.cpp +++ b/cpp/Platform.Exceptions.Tests/Ignore/EnsureExtensions.cpp @@ -1,9 +1,7 @@ -namespace Platform::Exceptions::Tests::Ignore +namespace Platform::Exceptions::Tests::Ignore::Always { - class EnsureExtensions + void ArgumentNotNull(auto argument, const std::string& argumentName) + requires std::is_pointer_v || std::is_null_pointer_v { - public: template static void ArgumentNotNull(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, TArgument* argument, std::string argumentName) - { - } - }; + } } diff --git a/cpp/Platform.Exceptions.Tests/Ignore/IgnoredEnsuranceTests.cpp b/cpp/Platform.Exceptions.Tests/Ignore/IgnoredEnsuranceTests.cpp index 587afde..e09517a 100644 --- a/cpp/Platform.Exceptions.Tests/Ignore/IgnoredEnsuranceTests.cpp +++ b/cpp/Platform.Exceptions.Tests/Ignore/IgnoredEnsuranceTests.cpp @@ -1,10 +1,7 @@ namespace Platform::Exceptions::Tests::Ignore { - TEST_CLASS(IgnoredEnsuranceTests) + TEST(IgnoredEnsuranceTests, EnsuranceIgnoredTest) { - public: TEST_METHOD(EnsuranceIgnoredTest) - { - Platform::Exceptions::EnsureExtensions::ArgumentNotNull(Platform::Exceptions::Ensure::Always, {}, "object"); - } + EXPECT_NO_THROW(Always::ArgumentNotNull(nullptr, "object")); }; } diff --git a/cpp/Platform.Exceptions.Tests/IgnoredEnsuranceTests.cpp b/cpp/Platform.Exceptions.Tests/IgnoredEnsuranceTests.cpp deleted file mode 100644 index 5f25f6d..0000000 --- a/cpp/Platform.Exceptions.Tests/IgnoredEnsuranceTests.cpp +++ /dev/null @@ -1,10 +0,0 @@ -namespace Platform::Exceptions::Tests::Ignore -{ - TEST_CLASS(IgnoredEnsurance) - { - public: TEST_METHOD(EnsuranceIgnoredTest) - { - Platform::Exceptions::EnsureExtensions::ArgumentNotNull(Platform::Exceptions::Ensure::Always, nullptr, "object"); - } - }; -} diff --git a/cpp/Platform.Exceptions/Ensure.h b/cpp/Platform.Exceptions/Ensure.h index 89fa6be..d5ced65 100644 --- a/cpp/Platform.Exceptions/Ensure.h +++ b/cpp/Platform.Exceptions/Ensure.h @@ -1,9 +1 @@ -namespace Platform::Exceptions -{ - class Ensure - { - public: inline static Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot Always; - - public: inline static Platform::Exceptions::ExtensionRoots::EnsureOnDebugExtensionRoot OnDebug; - }; -} +/// Not need diff --git a/cpp/Platform.Exceptions/EnsureExtensions.h b/cpp/Platform.Exceptions/EnsureExtensions.h index 0985170..7d1c6bd 100644 --- a/cpp/Platform.Exceptions/EnsureExtensions.h +++ b/cpp/Platform.Exceptions/EnsureExtensions.h @@ -1,41 +1,48 @@ -namespace Platform::Exceptions +namespace Platform::Exceptions::Always { - class EnsureExtensions + void ArgumentNotNull(auto argument, const std::string& argumentName, const std::string& message) + requires std::is_pointer_v || std::is_null_pointer_v { - public: template static void ArgumentNotNull(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, TArgument* argument, std::string argumentName, std::string message) + if (argument == nullptr) { - if (argument == nullptr) - { - throw std::invalid_argument(std::string("Argument ").append(argumentName).append(" is null: ").append(message).append(1, '.')); - } + throw std::invalid_argument(std::string("Argument ").append(argumentName).append(" is null: ").append(message).append(1, '.')); } + } - public: template static void ArgumentNotNull(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, TArgument* argument, std::string argumentName) { ArgumentNotNull(root, argument, argumentName, std::string("Argument ").append(argumentName).append(" is null.")); } - - public: template static void ArgumentNotNull(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, TArgument* argument) { ArgumentNotNull(root, argument, {}); } - - public: template static void ArgumentMeetsCriteria(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, TArgument argument, std::function predicate, std::string argumentName, std::string message) + void ArgumentNotNull(auto argument, const std::string& argumentName) + requires std::is_pointer_v || std::is_null_pointer_v + { + if (argument == nullptr) { - if (!predicate(argument)) - { - throw std::invalid_argument(std::string("Invalid ").append(argumentName).append(" argument: ").append(message).append(1, '.')); - } + throw std::invalid_argument(std::string("Argument ").append(argumentName).append(" is null.")); } + } - public: template static void ArgumentMeetsCriteria(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, TArgument argument, std::function predicate, std::string argumentName) { ArgumentMeetsCriteria(root, argument, predicate, argumentName, std::string("Argument ").append(argumentName).append(" does not meet the criteria.")); } - - public: template static void ArgumentMeetsCriteria(Platform::Exceptions::ExtensionRoots::EnsureAlwaysExtensionRoot root, TArgument argument, std::function predicate) { ArgumentMeetsCriteria(root, argument, predicate, {}); } - - public: template static void ArgumentNotNull(Platform::Exceptions::ExtensionRoots::EnsureOnDebugExtensionRoot root, TArgument* argument, std::string argumentName, std::string message) { Platform::Exceptions::EnsureExtensions::ArgumentNotNull(Platform::Exceptions::Ensure::Always, argument, argumentName, message); } - - public: template static void ArgumentNotNull(Platform::Exceptions::ExtensionRoots::EnsureOnDebugExtensionRoot root, TArgument* argument, std::string argumentName) { Platform::Exceptions::EnsureExtensions::ArgumentNotNull(Platform::Exceptions::Ensure::Always, argument, argumentName); } - - public: template static void ArgumentNotNull(Platform::Exceptions::ExtensionRoots::EnsureOnDebugExtensionRoot root, TArgument* argument) { Platform::Exceptions::EnsureExtensions::ArgumentNotNull(Platform::Exceptions::Ensure::Always, argument); } + void ArgumentNotNull(auto argument) + requires std::is_pointer_v || std::is_null_pointer_v + { + if (argument == nullptr) + { + throw std::invalid_argument(std::string("Argument is null.")); + } + } - public: template static void ArgumentMeetsCriteria(Platform::Exceptions::ExtensionRoots::EnsureOnDebugExtensionRoot root, TArgument argument, std::function predicate, std::string argumentName, std::string message) { Platform::Exceptions::EnsureExtensions::ArgumentMeetsCriteria(Platform::Exceptions::Ensure::Always, argument, predicate, argumentName, message); } + void ArgumentMeetsCriteria(auto&& argument, auto&& predicate, const std::string& argumentName, const std::string& message) + requires requires { { predicate(argument) } -> std::integral; } + { + if (not predicate(std::forward(argument))) + { + throw std::invalid_argument(std::string("Invalid ").append(argumentName).append(" argument: ").append(message).append(1, '.')); + } + } - public: template static void ArgumentMeetsCriteria(Platform::Exceptions::ExtensionRoots::EnsureOnDebugExtensionRoot root, TArgument argument, std::function predicate, std::string argumentName) { Platform::Exceptions::EnsureExtensions::ArgumentMeetsCriteria(Platform::Exceptions::Ensure::Always, argument, predicate, argumentName); } + void ArgumentMeetsCriteria(auto&& argument, auto&& predicate, const std::string& argumentName) + { + ArgumentMeetsCriteria(std::forward(argument), predicate, argumentName, std::string("Argument ").append(argumentName).append(" does not meet the criteria.")); + } - public: template static void ArgumentMeetsCriteria(Platform::Exceptions::ExtensionRoots::EnsureOnDebugExtensionRoot root, TArgument argument, std::function predicate) { Platform::Exceptions::EnsureExtensions::ArgumentMeetsCriteria(Platform::Exceptions::Ensure::Always, argument, predicate); } - }; + void ArgumentMeetsCriteria(auto&& argument, auto&& predicate) + { + ArgumentMeetsCriteria(std::forward(argument), predicate, {}); + } } diff --git a/cpp/Platform.Exceptions/ExceptionExtensions.h b/cpp/Platform.Exceptions/ExceptionExtensions.h index e2e6617..843cca6 100644 --- a/cpp/Platform.Exceptions/ExceptionExtensions.h +++ b/cpp/Platform.Exceptions/ExceptionExtensions.h @@ -1,34 +1,39 @@ namespace Platform::Exceptions { - class ExceptionExtensions + namespace Internal { - public: inline static std::string ExceptionContentsSeparator = "---"; - - public: inline static std::string ExceptionStringBuildingFailed = "Unable to format exception."; - - public: static void Ignore(const std::exception& exception) { IgnoredExceptions::RaiseExceptionIgnoredEvent(exception); } - - public: static std::string ToStringWithAllInnerExceptions(const std::exception& exception) + void Indent(std::string& sb, std::integral auto level) { - try - { - std::string sb; - BuildExceptionString(sb, exception, 0); - return sb; - } - catch (const std::exception& ex) - { - Platform::Exceptions::ExceptionExtensions::Ignore(ex); - return ExceptionStringBuildingFailed; - } + sb.append(level, '\t'); } - private: static void BuildExceptionString(std::string& sb, const std::exception& exception, std::int32_t level) + void BuildExceptionString(std::string& sb, const std::exception& exception, std::integral auto level) { Indent(sb, level); sb.append(exception.what()).append(1, '\n'); } + } + + static const std::string ExceptionContentsSeparator = "---"; + + static const std::string ExceptionStringBuildingFailed = "Unable to format exception."; + + static void Ignore(const std::exception& exception) { IgnoredExceptions::RaiseExceptionIgnoredEvent(exception); } + + static std::string ToStringWithAllInnerExceptions(const std::exception& exception) + { + try + { + std::string sb; + Internal::BuildExceptionString(sb, exception, 0); + return sb; + } + catch (const std::exception& ex) + { + Ignore(ex); + return ExceptionStringBuildingFailed; + } + } + - private: static void Indent(std::string& sb, std::int32_t level) { sb.append(level, '\t'); } - }; } diff --git a/cpp/Platform.Exceptions/ExtensionRoots/EnsureAlwaysExtensionRoot.h b/cpp/Platform.Exceptions/ExtensionRoots/EnsureAlwaysExtensionRoot.h index 63bbed2..5ecbef6 100644 --- a/cpp/Platform.Exceptions/ExtensionRoots/EnsureAlwaysExtensionRoot.h +++ b/cpp/Platform.Exceptions/ExtensionRoots/EnsureAlwaysExtensionRoot.h @@ -1,6 +1 @@ -namespace Platform::Exceptions::ExtensionRoots -{ - class EnsureAlwaysExtensionRoot - { - }; -} +/// No need diff --git a/cpp/Platform.Exceptions/ExtensionRoots/EnsureOnDebugExtensionRoot.h b/cpp/Platform.Exceptions/ExtensionRoots/EnsureOnDebugExtensionRoot.h index ac2e63e..5ecbef6 100644 --- a/cpp/Platform.Exceptions/ExtensionRoots/EnsureOnDebugExtensionRoot.h +++ b/cpp/Platform.Exceptions/ExtensionRoots/EnsureOnDebugExtensionRoot.h @@ -1,6 +1 @@ -namespace Platform::Exceptions::ExtensionRoots -{ - class EnsureOnDebugExtensionRoot - { - }; -} +/// No need diff --git a/cpp/Platform.Exceptions/ExtensionRoots/ThrowExtensionRoot.h b/cpp/Platform.Exceptions/ExtensionRoots/ThrowExtensionRoot.h index ff4e9ac..5ecbef6 100644 --- a/cpp/Platform.Exceptions/ExtensionRoots/ThrowExtensionRoot.h +++ b/cpp/Platform.Exceptions/ExtensionRoots/ThrowExtensionRoot.h @@ -1,6 +1 @@ -namespace Platform::Exceptions::ExtensionRoots -{ - class ThrowExtensionRoot - { - }; -} +/// No need diff --git a/cpp/Platform.Exceptions/IgnoredExceptions.h b/cpp/Platform.Exceptions/IgnoredExceptions.h index b4d8291..73ee944 100644 --- a/cpp/Platform.Exceptions/IgnoredExceptions.h +++ b/cpp/Platform.Exceptions/IgnoredExceptions.h @@ -12,7 +12,7 @@ namespace Platform::Exceptions public: static void RaiseExceptionIgnoredEvent(const std::exception& exception) { ExceptionIgnored({}, exception); } - private: static void OnExceptionIgnored(void *sender, const std::exception& exception) + private: static void OnExceptionIgnored(void* sender, const std::exception& exception) { if (CollectExceptions) { diff --git a/cpp/Platform.Exceptions/Platform.Exceptions.TemplateLibrary.nuspec b/cpp/Platform.Exceptions/Platform.Exceptions.TemplateLibrary.nuspec index b766949..f98675f 100644 --- a/cpp/Platform.Exceptions/Platform.Exceptions.TemplateLibrary.nuspec +++ b/cpp/Platform.Exceptions/Platform.Exceptions.TemplateLibrary.nuspec @@ -5,9 +5,9 @@ LinksPlatform's Platform.Exceptions Template Library LinksPlatform's Platform.Exceptions is a Template Library what contains abstract class templates. LinksPlatform's Platform.Exceptions is a Template Library what contains set of C++ abstract class templates. Use Platform.Exceptions.h file to include the library. - Platform.Delegates.TemplateLibrary dependency updated from 0.0.14 to 0.0.15. - Fixed compile error. - 0.0.16 + Platform.Delegates.TemplateLibrary dependency updated from 0.0.15 to 0.1.3 + Modernized C++ code + 0.1.0 Konstantin Diachenko Konstantin Diachenko Konstantin Diachenko @@ -19,7 +19,7 @@ true - + diff --git a/cpp/Platform.Exceptions/Throw.h b/cpp/Platform.Exceptions/Throw.h index 08aeb0b..5ecbef6 100644 --- a/cpp/Platform.Exceptions/Throw.h +++ b/cpp/Platform.Exceptions/Throw.h @@ -1,7 +1 @@ -namespace Platform::Exceptions -{ - class Throw - { - public: inline static Platform::Exceptions::ExtensionRoots::ThrowExtensionRoot A; - }; -} +/// No need diff --git a/cpp/Platform.Exceptions/ThrowExtensions.h b/cpp/Platform.Exceptions/ThrowExtensions.h index 7370f74..56d401a 100644 --- a/cpp/Platform.Exceptions/ThrowExtensions.h +++ b/cpp/Platform.Exceptions/ThrowExtensions.h @@ -1,13 +1,10 @@ namespace Platform::Exceptions { - class ThrowExtensions - { - public: static void NotSupportedException(Platform::Exceptions::ExtensionRoots::ThrowExtensionRoot root) { throw std::logic_error("Not supported exception."); } + void NotSupportedException() { throw std::logic_error("Not supported exception."); } - public: template static TReturn NotSupportedExceptionAndReturn(Platform::Exceptions::ExtensionRoots::ThrowExtensionRoot root) { throw std::logic_error("Not supported exception."); } + auto NotSupportedExceptionAndReturn() { throw std::logic_error("Not supported exception."); } - public: static void NotImplementedException(Platform::Exceptions::ExtensionRoots::ThrowExtensionRoot root) { throw std::logic_error("Not implemented exception."); } + void NotImplementedException() { throw std::logic_error("Not implemented exception."); } - public: template static TReturn NotImplementedExceptionAndReturn(Platform::Exceptions::ExtensionRoots::ThrowExtensionRoot root) { throw std::logic_error("Not implemented exception."); } - }; + auto NotImplementedExceptionAndReturn() { throw std::logic_error("Not implemented exception."); } } diff --git a/cpp/conanfile.txt b/cpp/conanfile.txt new file mode 100644 index 0000000..9bf92cd --- /dev/null +++ b/cpp/conanfile.txt @@ -0,0 +1,6 @@ +[requires] +gtest/cci.20210126 +platform.delegates/0.1.3 + +[generators] +cmake