aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorEgor Tensin <Egor.Tensin@gmail.com>2020-10-14 01:57:40 +0300
committerEgor Tensin <Egor.Tensin@gmail.com>2020-10-14 01:57:40 +0300
commit0e439fb2d229808a8d879bfefcf371099b522479 (patch)
treef2fc08d91f11cfae1dbd618be317b8d041f48903
parentinitial commit (diff)
downloadwinapi-common-0e439fb2d229808a8d879bfefcf371099b522479.tar.gz
winapi-common-0e439fb2d229808a8d879bfefcf371099b522479.zip
add Handle class
It's derived from various projects of mine.
-rw-r--r--.gitmodules3
-rw-r--r--CMakeLists.txt19
m---------cmake0
-rw-r--r--include/winapi/handle.hpp73
-rw-r--r--include/winapi/workarounds.hpp8
-rw-r--r--test/CMakeLists.txt11
-rw-r--r--test/handle.cpp25
-rw-r--r--test/main.cpp7
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>