diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2020-10-14 01:57:40 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2020-10-14 01:57:40 +0300 |
commit | 0e439fb2d229808a8d879bfefcf371099b522479 (patch) | |
tree | f2fc08d91f11cfae1dbd618be317b8d041f48903 | |
parent | initial commit (diff) | |
download | winapi-common-0e439fb2d229808a8d879bfefcf371099b522479.tar.gz winapi-common-0e439fb2d229808a8d879bfefcf371099b522479.zip |
add Handle class
It's derived from various projects of mine.
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | CMakeLists.txt | 19 | ||||
m--------- | cmake | 0 | ||||
-rw-r--r-- | include/winapi/handle.hpp | 73 | ||||
-rw-r--r-- | include/winapi/workarounds.hpp | 8 | ||||
-rw-r--r-- | test/CMakeLists.txt | 11 | ||||
-rw-r--r-- | test/handle.cpp | 25 | ||||
-rw-r--r-- | test/main.cpp | 7 |
8 files changed, 146 insertions, 0 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..d65ecb9 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "cmake"] + path = cmake + url = https://github.com/egor-tensin/cmake-common.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ef5747e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.5) # for Boost::* imported targets + +project(winapi_common CXX) + +include(cmake/common.cmake) + +find_package(Boost REQUIRED) + +add_library(winapi_common INTERFACE) +target_include_directories(winapi_common INTERFACE include/) +target_link_libraries(winapi_common INTERFACE Boost::disable_autolinking Boost::headers) + +install(DIRECTORY include/winapi DESTINATION include) + +if(WINAPI_COMMON_TESTS) + add_subdirectory(test) +endif() + +install(FILES LICENSE.txt DESTINATION share) diff --git a/cmake b/cmake new file mode 160000 +Subproject 62a426a08b7d16e58f0c906ed382aceb9bcb9aa diff --git a/include/winapi/handle.hpp b/include/winapi/handle.hpp new file mode 100644 index 0000000..9e9661b --- /dev/null +++ b/include/winapi/handle.hpp @@ -0,0 +1,73 @@ +// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> +// This file is part of the "winapi-common" project. +// For details, see https://github.com/egor-tensin/winapi-common. +// Distributed under the MIT License. + +#pragma once + +#include "workarounds.hpp" + +#include <boost/config.hpp> + +#include <windows.h> + +#include <cassert> +#include <memory> +#include <utility> + +namespace winapi { + +class Handle { +public: + Handle() = default; + + explicit Handle(HANDLE raw) + : impl{raw} + { } + + Handle(Handle&& other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); + } + + Handle& operator=(Handle other) BOOST_NOEXCEPT_OR_NOTHROW { + swap(other); + return *this; + } + + void swap(Handle& other) BOOST_NOEXCEPT_OR_NOTHROW { + using std::swap; + swap(impl, other.impl); + } + + explicit operator HANDLE() const { return impl.get(); } + +private: + struct Close { + void operator()(HANDLE raw) const { + if (raw == NULL || raw == INVALID_HANDLE_VALUE) + return; + const auto ret = ::CloseHandle(raw); + assert(ret); + WINAPI_UNUSED_PARAMETER(ret); + } + }; + + std::unique_ptr<void, Close> impl; + + Handle(const Handle&) = delete; +}; + +inline void swap(Handle& a, Handle& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + +} + +namespace std { + +template <> +inline void swap(winapi::Handle& a, winapi::Handle& b) BOOST_NOEXCEPT_OR_NOTHROW { + a.swap(b); +} + +} // namespace std diff --git a/include/winapi/workarounds.hpp b/include/winapi/workarounds.hpp new file mode 100644 index 0000000..a5a3607 --- /dev/null +++ b/include/winapi/workarounds.hpp @@ -0,0 +1,8 @@ +// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> +// This file is part of the "winapi-common" project. +// For details, see https://github.com/egor-tensin/winapi-common. +// Distributed under the MIT License. + +#pragma once + +#define WINAPI_UNUSED_PARAMETER(...) (void)(__VA_ARGS__) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..3c23426 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1,11 @@ +find_package(Boost REQUIRED COMPONENTS unit_test_framework) + +add_executable(unit_tests main.cpp handle.cpp) +target_link_libraries(unit_tests PRIVATE winapi_common) +target_link_libraries(unit_tests PRIVATE Boost::disable_autolinking Boost::unit_test_framework) +set_target_properties(unit_tests PROPERTIES OUTPUT_NAME winapi-common-unit-tests) + +install(TARGETS unit_tests RUNTIME DESTINATION bin) +if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + install(FILES "$<TARGET_PDB_FILE:unit_tests>" DESTINATION bin OPTIONAL) +endif() diff --git a/test/handle.cpp b/test/handle.cpp new file mode 100644 index 0000000..32b5bc1 --- /dev/null +++ b/test/handle.cpp @@ -0,0 +1,25 @@ +// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> +// This file is part of the "winapi-common" project. +// For details, see https://github.com/egor-tensin/winapi-common. +// Distributed under the MIT License. + +#include <winapi/handle.hpp> + +#include <boost/test/unit_test.hpp> + +#include <windows.h> + +BOOST_AUTO_TEST_SUITE(handle_tests) + +BOOST_AUTO_TEST_CASE(null) { + { + winapi::Handle h{NULL}; + } + BOOST_TEST(true, "NULL handle closed successfully"); + { + winapi::Handle h{INVALID_HANDLE_VALUE}; + } + BOOST_TEST(true, "INVALID_HANDLE_VALUE handle closed successfully"); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/test/main.cpp b/test/main.cpp new file mode 100644 index 0000000..d7e8d4f --- /dev/null +++ b/test/main.cpp @@ -0,0 +1,7 @@ +// Copyright (c) 2020 Egor Tensin <Egor.Tensin@gmail.com> +// This file is part of the "winapi-common" project. +// For details, see https://github.com/egor-tensin/winapi-common. +// Distributed under the MIT License. + +#define BOOST_TEST_MODULE winapi_common tests +#include <boost/test/unit_test.hpp> |