Last active
May 22, 2020 16:42
-
-
Save stefanofiorentino/f49e459210b462b797ca884c05040887 to your computer and use it in GitHub Desktop.
Patch to work with @amurzeau https://github.com/stefanofiorentino/uvw/commit/f04d5b5dc8bbacbbc71212b5d0ad51eb059c6bbe.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From c1bc3bf02474fc4aa44e81b153e49b039a1f74b7 Mon Sep 17 00:00:00 2001 | |
From: "Fiorentino Ing. Stefano" <[email protected]> | |
Date: Fri, 22 May 2020 18:40:28 +0200 | |
Subject: [PATCH] (extern) explicit instantiation of a type_factory | |
Signed-off-by: Fiorentino Ing. Stefano <[email protected]> | |
--- | |
.github/workflows/build.yml | 45 +- | |
...41fa871a7e818a75275294b82d2b3555ca79.patch | 1606 +++++++++++++++++ | |
src/CMakeLists.txt | 15 +- | |
src/uvw.hpp | 241 +++ | |
src/uvw/async.h | 8 +- | |
src/uvw/check.h | 8 +- | |
src/uvw/config.h | 38 +- | |
src/uvw/dns.h | 29 +- | |
src/uvw/emitter.h | 37 +- | |
src/uvw/fs.h | 11 +- | |
src/uvw/fs_event.h | 10 +- | |
src/uvw/fs_poll.h | 9 +- | |
src/uvw/handle.hpp | 16 +- | |
src/uvw/idle.h | 9 +- | |
src/uvw/lib.h | 7 +- | |
src/uvw/loop.h | 15 +- | |
src/uvw/pipe.h | 7 +- | |
src/uvw/poll.h | 10 +- | |
src/uvw/prepare.h | 9 +- | |
src/uvw/process.h | 10 +- | |
src/uvw/request.hpp | 5 + | |
src/uvw/resource.hpp | 5 + | |
src/uvw/signal.h | 9 +- | |
src/uvw/stream.cpp | 13 + | |
src/uvw/stream.h | 70 +- | |
src/uvw/tcp.h | 31 +- | |
src/uvw/thread.h | 21 +- | |
src/uvw/timer.h | 9 +- | |
src/uvw/tty.h | 9 +- | |
src/uvw/type_factory/type_factory.cpp | 264 +++ | |
src/uvw/type_factory/type_factory.h | 18 + | |
src/uvw/udp.h | 89 +- | |
src/uvw/underlying_type.hpp | 5 + | |
src/uvw/util.cpp | 4 + | |
src/uvw/util.h | 38 +- | |
src/uvw/work.h | 9 +- | |
test/CMakeLists.txt | 2 +- | |
test/main.cpp | 186 +- | |
test/uvw/emitter.cpp | 8 - | |
test/uvw/handle.cpp | 12 - | |
test/uvw/thread.cpp | 1 + | |
test/uvw/tty.cpp | 1 - | |
test/uvw/util.cpp | 1 - | |
43 files changed, 2616 insertions(+), 334 deletions(-) | |
create mode 100644 5ca341fa871a7e818a75275294b82d2b3555ca79.patch | |
create mode 100644 src/uvw/type_factory/type_factory.cpp | |
create mode 100644 src/uvw/type_factory/type_factory.h | |
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml | |
index 0591182..055ff7e 100644 | |
--- a/.github/workflows/build.yml | |
+++ b/.github/workflows/build.yml | |
@@ -3,31 +3,6 @@ name: build | |
on: [push, pull_request] | |
jobs: | |
- | |
- linux: | |
- timeout-minutes: 60 | |
- runs-on: ubuntu-latest | |
- | |
- strategy: | |
- matrix: | |
- compiler: [g++, clang++] | |
- mode: [-DBUILD_UVW_LIBS=ON, -DBUILD_UVW_LIBS=OFF] | |
- | |
- steps: | |
- - uses: actions/checkout@v1 | |
- - name: Compile tests | |
- working-directory: build | |
- env: | |
- CXX: ${{ matrix.compiler }} | |
- run: | | |
- cmake ${{ matrix.mode }} -DBUILD_TESTING=ON -Dlibuv_buildtests=OFF .. | |
- make -j4 | |
- - name: Run tests | |
- working-directory: build | |
- env: | |
- CTEST_OUTPUT_ON_FAILURE: 1 | |
- run: ctest --timeout 5 -C Debug -j4 | |
- | |
windows: | |
timeout-minutes: 60 | |
runs-on: windows-latest | |
@@ -35,7 +10,7 @@ jobs: | |
strategy: | |
matrix: | |
generator: [Visual Studio 16 2019] | |
- mode: [-DBUILD_UVW_LIBS=ON, -DBUILD_UVW_LIBS=OFF] | |
+ mode: [-DBUILD_UVW_LIBS=ON] | |
steps: | |
- uses: actions/checkout@v1 | |
@@ -43,20 +18,4 @@ jobs: | |
working-directory: build | |
run: | | |
cmake ${{ matrix.mode }} -DBUILD_TESTING=ON -Dlibuv_buildtests=OFF -DCMAKE_CXX_FLAGS=/W1 -G"${{ matrix.generator }}" .. | |
- cmake --build . -j 4 | |
- | |
- macos: | |
- timeout-minutes: 60 | |
- runs-on: macOS-latest | |
- | |
- strategy: | |
- matrix: | |
- mode: [-DBUILD_UVW_LIBS=ON, -DBUILD_UVW_LIBS=OFF] | |
- | |
- steps: | |
- - uses: actions/checkout@v1 | |
- - name: Compile tests | |
- working-directory: build | |
- run: | | |
- cmake ${{ matrix.mode }} -DBUILD_TESTING=ON -Dlibuv_buildtests=OFF .. | |
- make -j4 | |
+ cmake --build . -j 4 | |
\ No newline at end of file | |
diff --git a/5ca341fa871a7e818a75275294b82d2b3555ca79.patch b/5ca341fa871a7e818a75275294b82d2b3555ca79.patch | |
new file mode 100644 | |
index 0000000..2d7c143 | |
--- /dev/null | |
+++ b/5ca341fa871a7e818a75275294b82d2b3555ca79.patch | |
@@ -0,0 +1,1606 @@ | |
+From 5ca341fa871a7e818a75275294b82d2b3555ca79 Mon Sep 17 00:00:00 2001 | |
+From: test <[email protected]> | |
+Date: Sun, 17 May 2020 02:22:29 +0200 | |
+Subject: [PATCH] shared libs: export classes with functions implemented in | |
+ .cpp files | |
+ | |
+When building a DLL on Windows or building a shared library with | |
+`-fvisibility=hidden` on Unix, class with functions implemented in a cpp | |
+file must be exported. | |
+ | |
+This mean `__declspec(dllexport)` on Windows, and | |
+`__attribute__((visibility(default)))` on Unix. | |
+ | |
+Changes made: | |
+ - `UVW_EXTERN` on all non templated classes. | |
+ | |
+ - Declare `UVW_EXTERN` in config.h. | |
+ | |
+ - Put `UVW_EXTERN` on all extern explicit template instantiations. | |
+ | |
+ - Put `UVW_EXTERN` on instantiation of `Flags<T>` from an exported template. | |
+ MSVC was throwing a `C4251` warning for these, so I'm exported them too | |
+ via an explicit template instantiation. This is not required for the code | |
+ to link in fact. | |
+ | |
+ - Also add `UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE()` for MSVC as it | |
+ outputs many `C4251` warnings when an exported class uses a non exported | |
+ template in the standard library. This means the user of the DLL must use | |
+ similar enough compiler and flags so the C++ ABI is the same. | |
+ There are these macro in all headers so the warning is still enabled for | |
+ user code, if the user happen to use `__declspec(dllexport)` too. | |
+ | |
+ - Almost all exported classes derive from a template class. This doesn't | |
+ trigger warning `C4275` because the base template class use the derived | |
+ class in its template arguments. See last point here: https://docs.microsoft.com/en-us/cpp/cpp/general-rules-and-limitations?view=vs-2019 | |
+ | |
+ - Change tests link libraries to use `uvw-shared` and `uv-shared` instead. | |
+ So this will test that functions are really available from the DLL/.so. | |
+ | |
+ - Add CMake code to declare `USING_UVW_SHARED` or `BUILDING_UVW_SHARED` as | |
+ appropriate. | |
+ | |
+ - Enable `CXX_VISIBILITY_HIDDEN` so only explicitly exported symbols are | |
+ exported. | |
+ | |
+Currently not working because of static variables in `Emitter<>::next_type()` | |
+and `Emitter<>::event_type<>()`. | |
+ | |
+Fixes: #196 | |
+--- | |
+ src/CMakeLists.txt | 14 +++++- | |
+ src/uvw/async.h | 8 +++- | |
+ src/uvw/check.h | 8 +++- | |
+ src/uvw/config.h | 38 +++++++++++++++- | |
+ src/uvw/dns.h | 29 +++++++----- | |
+ src/uvw/emitter.h | 15 ++++++- | |
+ src/uvw/fs.h | 11 +++-- | |
+ src/uvw/fs_event.h | 10 ++++- | |
+ src/uvw/fs_poll.h | 9 +++- | |
+ src/uvw/handle.hpp | 7 ++- | |
+ src/uvw/idle.h | 9 +++- | |
+ src/uvw/lib.h | 7 ++- | |
+ src/uvw/loop.h | 15 ++++--- | |
+ src/uvw/pipe.h | 7 ++- | |
+ src/uvw/poll.h | 10 ++++- | |
+ src/uvw/prepare.h | 9 +++- | |
+ src/uvw/process.h | 10 ++++- | |
+ src/uvw/request.hpp | 5 +++ | |
+ src/uvw/resource.hpp | 5 +++ | |
+ src/uvw/signal.h | 9 +++- | |
+ src/uvw/stream.h | 19 +++++--- | |
+ src/uvw/tcp.h | 31 +++++++------ | |
+ src/uvw/thread.h | 21 +++++---- | |
+ src/uvw/timer.h | 9 +++- | |
+ src/uvw/tty.h | 9 +++- | |
+ src/uvw/udp.h | 89 ++++++++++++++++++++----------------- | |
+ src/uvw/underlying_type.hpp | 5 +++ | |
+ src/uvw/util.cpp | 4 ++ | |
+ src/uvw/util.h | 38 +++++++++------- | |
+ src/uvw/work.h | 9 +++- | |
+ test/CMakeLists.txt | 4 +- | |
+ 31 files changed, 334 insertions(+), 139 deletions(-) | |
+ | |
+diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt | |
+index 25e6c12..af19cd6 100644 | |
+--- a/src/CMakeLists.txt | |
++++ b/src/CMakeLists.txt | |
+@@ -74,8 +74,20 @@ add_uvw_library(uvw-static) | |
+ add_library(uvw-shared SHARED) | |
+ add_library(uvw::uvw-shared ALIAS uvw-shared) | |
+ target_link_libraries(uvw-shared PUBLIC uv::uv-shared) | |
+-set_target_properties(uvw-shared PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${UVW_VERSION_MAJOR} EXCLUDE_FROM_DEFAULT_BUILD 1) | |
++set_target_properties(uvw-shared PROPERTIES | |
++ VERSION ${PROJECT_VERSION} | |
++ SOVERSION ${UVW_VERSION_MAJOR} | |
++ EXCLUDE_FROM_DEFAULT_BUILD 1 | |
++ C_VISIBILITY_PRESET hidden | |
++ CXX_VISIBILITY_PRESET hidden | |
++) | |
+ add_uvw_library(uvw-shared) | |
++target_compile_definitions(uvw-shared | |
++ INTERFACE | |
++ USING_UVW_SHARED=1 | |
++ PRIVATE | |
++ BUILDING_UVW_SHARED=1 | |
++) | |
+ | |
+ # | |
+ # Install targets | |
+diff --git a/src/uvw/async.h b/src/uvw/async.h | |
+index e326bac..4e6f4e3 100644 | |
+--- a/src/uvw/async.h | |
++++ b/src/uvw/async.h | |
+@@ -5,7 +5,9 @@ | |
+ #include <uv.h> | |
+ #include "handle.hpp" | |
+ #include "loop.h" | |
++#include "config.h" | |
+ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ namespace uvw { | |
+ | |
+@@ -15,7 +17,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by AsyncHandle according with its functionalities. | |
+ */ | |
+-struct AsyncEvent {}; | |
++struct UVW_EXTERN AsyncEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -26,7 +28,7 @@ struct AsyncEvent {}; | |
+ * | |
+ * To create an `AsyncHandle` through a `Loop`, no arguments are required. | |
+ */ | |
+-class AsyncHandle final: public Handle<AsyncHandle, uv_async_t> { | |
++class UVW_EXTERN AsyncHandle final : public Handle<AsyncHandle, uv_async_t> { | |
+ static void sendCallback(uv_async_t *handle); | |
+ | |
+ public: | |
+@@ -63,4 +65,6 @@ class AsyncHandle final: public Handle<AsyncHandle, uv_async_t> { | |
+ #include "async.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_ASYNC_INCLUDE_H | |
+diff --git a/src/uvw/check.h b/src/uvw/check.h | |
+index 4d3e571..79f6d37 100644 | |
+--- a/src/uvw/check.h | |
++++ b/src/uvw/check.h | |
+@@ -5,7 +5,9 @@ | |
+ #include <uv.h> | |
+ #include "handle.hpp" | |
+ #include "loop.h" | |
++#include "config.h" | |
+ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ namespace uvw { | |
+ | |
+@@ -15,7 +17,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by CheckHandle according with its functionalities. | |
+ */ | |
+-struct CheckEvent {}; | |
++struct UVW_EXTERN CheckEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -26,7 +28,7 @@ struct CheckEvent {}; | |
+ * | |
+ * To create a `CheckHandle` through a `Loop`, no arguments are required. | |
+ */ | |
+-class CheckHandle final: public Handle<CheckHandle, uv_check_t> { | |
++class UVW_EXTERN CheckHandle final : public Handle<CheckHandle, uv_check_t> { | |
+ static void startCallback(uv_check_t *handle); | |
+ | |
+ public: | |
+@@ -60,4 +62,6 @@ class CheckHandle final: public Handle<CheckHandle, uv_check_t> { | |
+ #include "check.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_CHECK_INCLUDE_H | |
+diff --git a/src/uvw/config.h b/src/uvw/config.h | |
+index cfee0c9..429f8fe 100644 | |
+--- a/src/uvw/config.h | |
++++ b/src/uvw/config.h | |
+@@ -1,12 +1,48 @@ | |
+ #ifndef UVW_CONFIG_H | |
+ #define UVW_CONFIG_H | |
+ | |
++#if defined(BUILDING_UVW_SHARED) && defined(USING_UVW_SHARED) | |
++#error "Define either BUILDING_UVW_SHARED or USING_UVW_SHARED, not both." | |
++#endif | |
+ | |
+ #ifndef UVW_AS_LIB | |
+ #define UVW_INLINE inline | |
++#define UVW_EXTERN /* nothing */ | |
++#else /* UVW_AS_LIB */ | |
++#define UVW_INLINE /* nothing */ | |
++ | |
++#ifdef _WIN32 | |
++/* Windows - set up dll import/export decorators. */ | |
++#if defined(BUILDING_UVW_SHARED) | |
++/* Building shared library. */ | |
++#define UVW_EXTERN __declspec(dllexport) | |
++#elif defined(USING_UVW_SHARED) | |
++/* Using shared library. */ | |
++#define UVW_EXTERN __declspec(dllimport) | |
++#else | |
++/* Building static library. */ | |
++#define UVW_EXTERN /* nothing */ | |
++#endif | |
++#elif __GNUC__ >= 4 | |
++#define UVW_EXTERN __attribute__((visibility("default"))) | |
+ #else | |
+-#define UVW_INLINE | |
++#define UVW_EXTERN /* nothing */ | |
+ #endif | |
+ | |
++#endif /* UVW_AS_LIB */ | |
++ | |
++#if defined(_MSC_VER) && defined(UVW_AS_LIB) | |
++/* | |
++ * C4251: 'type' : class 'type1' needs to have dll-interface to be used by clients of class 'type2' | |
++ */ | |
++#define UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE() \ | |
++ __pragma(warning(push)) \ | |
++ __pragma(warning(disable: 4251)) | |
++#define UVW_MSVC_WARNING_POP() \ | |
++ __pragma(warning(pop)) | |
++#else | |
++#define UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE() | |
++#define UVW_MSVC_WARNING_POP() | |
++#endif | |
+ | |
+ #endif | |
+diff --git a/src/uvw/dns.h b/src/uvw/dns.h | |
+index e9b2e86..db90ddd 100644 | |
+--- a/src/uvw/dns.h | |
++++ b/src/uvw/dns.h | |
+@@ -9,6 +9,9 @@ | |
+ #include "request.hpp" | |
+ #include "util.h" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -19,7 +22,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by GetAddrInfoReq according with its functionalities. | |
+ */ | |
+-struct AddrInfoEvent { | |
++struct UVW_EXTERN AddrInfoEvent { | |
+ using Deleter = void(*)(addrinfo *); | |
+ | |
+ AddrInfoEvent(std::unique_ptr<addrinfo, Deleter> addr); | |
+@@ -39,7 +42,7 @@ struct AddrInfoEvent { | |
+ * | |
+ * It will be emitted by GetNameInfoReq according with its functionalities. | |
+ */ | |
+-struct NameInfoEvent { | |
++struct UVW_EXTERN NameInfoEvent { | |
+ NameInfoEvent(const char *host, const char *serv); | |
+ | |
+ /** | |
+@@ -68,7 +71,7 @@ struct NameInfoEvent { | |
+ * | |
+ * To create a `GetAddrInfoReq` through a `Loop`, no arguments are required. | |
+ */ | |
+-class GetAddrInfoReq final: public Request<GetAddrInfoReq, uv_getaddrinfo_t> { | |
++class UVW_EXTERN GetAddrInfoReq final: public Request<GetAddrInfoReq, uv_getaddrinfo_t> { | |
+ static void addrInfoCallback(uv_getaddrinfo_t *req, int status, addrinfo *res); | |
+ void nodeAddrInfo(const char *node, const char *service, addrinfo *hints = nullptr); | |
+ auto nodeAddrInfoSync(const char *node, const char *service, addrinfo *hints = nullptr); | |
+@@ -153,7 +156,7 @@ class GetAddrInfoReq final: public Request<GetAddrInfoReq, uv_getaddrinfo_t> { | |
+ * | |
+ * To create a `GetNameInfoReq` through a `Loop`, no arguments are required. | |
+ */ | |
+-class GetNameInfoReq final: public Request<GetNameInfoReq, uv_getnameinfo_t> { | |
++class UVW_EXTERN GetNameInfoReq final: public Request<GetNameInfoReq, uv_getnameinfo_t> { | |
+ static void nameInfoCallback(uv_getnameinfo_t *req, int status, const char *hostname, const char *service); | |
+ | |
+ public: | |
+@@ -232,17 +235,17 @@ class GetNameInfoReq final: public Request<GetNameInfoReq, uv_getnameinfo_t> { | |
+ | |
+ // (extern) explicit instantiations | |
+ | |
+-extern template void GetNameInfoReq::nameInfo<IPv4>(std::string ip, unsigned int port, int flags); | |
+-extern template void GetNameInfoReq::nameInfo<IPv6>(std::string ip, unsigned int port, int flags); | |
++extern template UVW_EXTERN void GetNameInfoReq::nameInfo<IPv4>(std::string ip, unsigned int port, int flags); | |
++extern template UVW_EXTERN void GetNameInfoReq::nameInfo<IPv6>(std::string ip, unsigned int port, int flags); | |
+ | |
+-extern template void GetNameInfoReq::nameInfo<IPv4>(Addr addr, int flags); | |
+-extern template void GetNameInfoReq::nameInfo<IPv6>(Addr addr, int flags); | |
++extern template UVW_EXTERN void GetNameInfoReq::nameInfo<IPv4>(Addr addr, int flags); | |
++extern template UVW_EXTERN void GetNameInfoReq::nameInfo<IPv6>(Addr addr, int flags); | |
+ | |
+-extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv4>(std::string ip, unsigned int port, int flags); | |
+-extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(std::string ip, unsigned int port, int flags); | |
++extern template UVW_EXTERN std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv4>(std::string ip, unsigned int port, int flags); | |
++extern template UVW_EXTERN std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(std::string ip, unsigned int port, int flags); | |
+ | |
+-extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv4>(Addr addr, int flags); | |
+-extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(Addr addr, int flags); | |
++extern template UVW_EXTERN std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv4>(Addr addr, int flags); | |
++extern template UVW_EXTERN std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(Addr addr, int flags); | |
+ | |
+ | |
+ } | |
+@@ -252,4 +255,6 @@ extern template std::pair<bool, std::pair<const char *, const char *>> GetNameIn | |
+ #include "dns.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_DNS_INCLUDE_H | |
+diff --git a/src/uvw/emitter.h b/src/uvw/emitter.h | |
+index a189f3a..c97e086 100644 | |
+--- a/src/uvw/emitter.h | |
++++ b/src/uvw/emitter.h | |
+@@ -11,6 +11,9 @@ | |
+ #include <memory> | |
+ #include <list> | |
+ #include <uv.h> | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -21,7 +24,7 @@ namespace uvw { | |
+ * | |
+ * Custom wrapper around error constants of `libuv`. | |
+ */ | |
+-struct ErrorEvent { | |
++struct UVW_EXTERN ErrorEvent { | |
+ template<typename U, typename = std::enable_if_t<std::is_integral_v<U>>> | |
+ explicit ErrorEvent(U val) noexcept | |
+ : ec{static_cast<int>(val)} | |
+@@ -190,6 +193,14 @@ class Emitter { | |
+ } | |
+ | |
+ public: | |
++ Emitter() = default; | |
++ Emitter(Emitter &&) = default; | |
++ Emitter & operator=(Emitter &&) = default; | |
++ | |
++ // These must be deleted because MSVC try to export them with UVW_EXPORT | |
++ Emitter(const Emitter&) = delete; | |
++ Emitter& operator=(const Emitter&) = delete; | |
++ | |
+ template<typename E> | |
+ using Listener = typename Handler<E>::Listener; | |
+ | |
+@@ -321,4 +332,6 @@ class Emitter { | |
+ #include "emitter.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_EMITTER_INCLUDE_H | |
+diff --git a/src/uvw/fs.h b/src/uvw/fs.h | |
+index c4af1d4..d4a1ea1 100644 | |
+--- a/src/uvw/fs.h | |
++++ b/src/uvw/fs.h | |
+@@ -10,6 +10,9 @@ | |
+ #include "request.hpp" | |
+ #include "util.h" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -433,7 +436,7 @@ class FsRequest: public Request<T, uv_fs_t> { | |
+ * [documentation](http://docs.libuv.org/en/v1.x/fs.html) | |
+ * for further details. | |
+ */ | |
+-class FileReq final: public FsRequest<FileReq> { | |
++class UVW_EXTERN FileReq final: public FsRequest<FileReq> { | |
+ static constexpr uv_file BAD_FD = -1; | |
+ | |
+ static void fsOpenCallback(uv_fs_t *req); | |
+@@ -784,7 +787,7 @@ class FileReq final: public FsRequest<FileReq> { | |
+ * [documentation](http://docs.libuv.org/en/v1.x/fs.html) | |
+ * for further details. | |
+ */ | |
+-class FsReq final: public FsRequest<FsReq> { | |
++class UVW_EXTERN FsReq final: public FsRequest<FsReq> { | |
+ static void fsReadlinkCallback(uv_fs_t *req); | |
+ static void fsReaddirCallback(uv_fs_t *req); | |
+ | |
+@@ -1425,7 +1428,7 @@ class FsReq final: public FsRequest<FsReq> { | |
+ | |
+ | |
+ /*! @brief Helper functions. */ | |
+-struct FsHelper { | |
++struct UVW_EXTERN FsHelper { | |
+ /** | |
+ * @brief Gets the OS dependent handle. | |
+ * | |
+@@ -1459,4 +1462,6 @@ struct FsHelper { | |
+ #include "fs.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_FS_INCLUDE_H | |
+diff --git a/src/uvw/fs_event.h b/src/uvw/fs_event.h | |
+index 6cbc5a0..ba15842 100644 | |
+--- a/src/uvw/fs_event.h | |
++++ b/src/uvw/fs_event.h | |
+@@ -8,6 +8,9 @@ | |
+ #include "handle.hpp" | |
+ #include "util.h" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -37,7 +40,7 @@ enum class UVFsEvent: std::underlying_type_t<uv_fs_event> { | |
+ * | |
+ * It will be emitted by FsEventHandle according with its functionalities. | |
+ */ | |
+-struct FsEventEvent { | |
++struct UVW_EXTERN FsEventEvent { | |
+ FsEventEvent(const char * pathname, Flags<details::UVFsEvent> events); | |
+ | |
+ /** | |
+@@ -58,6 +61,7 @@ struct FsEventEvent { | |
+ */ | |
+ Flags<details::UVFsEvent> flags; | |
+ }; | |
++template class UVW_EXTERN Flags<details::UVFsEvent>; | |
+ | |
+ | |
+ /** | |
+@@ -73,7 +77,7 @@ struct FsEventEvent { | |
+ * [documentation](http://docs.libuv.org/en/v1.x/fs_event.html) | |
+ * for further details. | |
+ */ | |
+-class FsEventHandle final: public Handle<FsEventHandle, uv_fs_event_t> { | |
++class UVW_EXTERN FsEventHandle final: public Handle<FsEventHandle, uv_fs_event_t> { | |
+ static void startCallback(uv_fs_event_t *handle, const char *filename, int events, int status); | |
+ | |
+ public: | |
+@@ -146,4 +150,6 @@ class FsEventHandle final: public Handle<FsEventHandle, uv_fs_event_t> { | |
+ #include "fs_event.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_FS_EVENT_INCLUDE_H | |
+diff --git a/src/uvw/fs_poll.h b/src/uvw/fs_poll.h | |
+index a264eb3..365669b 100644 | |
+--- a/src/uvw/fs_poll.h | |
++++ b/src/uvw/fs_poll.h | |
+@@ -8,6 +8,9 @@ | |
+ #include "handle.hpp" | |
+ #include "util.h" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -18,7 +21,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by FsPollHandle according with its functionalities. | |
+ */ | |
+-struct FsPollEvent { | |
++struct UVW_EXTERN FsPollEvent { | |
+ explicit FsPollEvent(Stat previous, Stat current) noexcept; | |
+ | |
+ Stat prev; /*!< The old Stat struct. */ | |
+@@ -35,7 +38,7 @@ struct FsPollEvent { | |
+ * | |
+ * To create a `FsPollHandle` through a `Loop`, no arguments are required. | |
+ */ | |
+-class FsPollHandle final: public Handle<FsPollHandle, uv_fs_poll_t> { | |
++class UVW_EXTERN FsPollHandle final: public Handle<FsPollHandle, uv_fs_poll_t> { | |
+ static void startCallback(uv_fs_poll_t *handle, int status, const uv_stat_t *prev, const uv_stat_t *curr); | |
+ | |
+ public: | |
+@@ -80,4 +83,6 @@ class FsPollHandle final: public Handle<FsPollHandle, uv_fs_poll_t> { | |
+ #include "fs_poll.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_FS_POLL_INCLUDE_H | |
+diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp | |
+index 274f4fc..f459ff5 100644 | |
+--- a/src/uvw/handle.hpp | |
++++ b/src/uvw/handle.hpp | |
+@@ -8,6 +8,9 @@ | |
+ #include <uv.h> | |
+ #include "resource.hpp" | |
+ #include "util.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -18,7 +21,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by the handles according with their functionalities. | |
+ */ | |
+-struct CloseEvent {}; | |
++struct UVW_EXTERN CloseEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -274,4 +277,6 @@ class Handle: public Resource<T, U>, public BaseHandle { | |
+ | |
+ } | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_HANDLE_INCLUDE_H | |
+diff --git a/src/uvw/idle.h b/src/uvw/idle.h | |
+index 28a8c12..af78ce1 100644 | |
+--- a/src/uvw/idle.h | |
++++ b/src/uvw/idle.h | |
+@@ -5,6 +5,9 @@ | |
+ #include <uv.h> | |
+ #include "handle.hpp" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -15,7 +18,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by IdleHandle according with its functionalities. | |
+ */ | |
+-struct IdleEvent {}; | |
++struct UVW_EXTERN IdleEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -34,7 +37,7 @@ struct IdleEvent {}; | |
+ * | |
+ * To create an `IdleHandle` through a `Loop`, no arguments are required. | |
+ */ | |
+-class IdleHandle final: public Handle<IdleHandle, uv_idle_t> { | |
++class UVW_EXTERN IdleHandle final: public Handle<IdleHandle, uv_idle_t> { | |
+ static void startCallback(uv_idle_t *handle); | |
+ | |
+ public: | |
+@@ -68,4 +71,6 @@ class IdleHandle final: public Handle<IdleHandle, uv_idle_t> { | |
+ #include "idle.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_IDLE_INCLUDE_H | |
+diff --git a/src/uvw/lib.h b/src/uvw/lib.h | |
+index 7e8fff1..b8e293d 100644 | |
+--- a/src/uvw/lib.h | |
++++ b/src/uvw/lib.h | |
+@@ -8,6 +8,9 @@ | |
+ #include <uv.h> | |
+ #include "loop.h" | |
+ #include "underlying_type.hpp" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -19,7 +22,7 @@ namespace uvw { | |
+ * `uvw` provides cross platform utilities for loading shared libraries and | |
+ * retrieving symbols from them, by means of the API offered by `libuv`. | |
+ */ | |
+-class SharedLib final: public UnderlyingType<SharedLib, uv_lib_t> { | |
++class UVW_EXTERN SharedLib final: public UnderlyingType<SharedLib, uv_lib_t> { | |
+ public: | |
+ explicit SharedLib(ConstructorAccess ca, std::shared_ptr<Loop> ref, std::string filename) noexcept; | |
+ | |
+@@ -67,4 +70,6 @@ class SharedLib final: public UnderlyingType<SharedLib, uv_lib_t> { | |
+ #include "lib.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_LIB_INCLUDE_H | |
+diff --git a/src/uvw/loop.h b/src/uvw/loop.h | |
+index 9832f0f..94c3a03 100644 | |
+--- a/src/uvw/loop.h | |
++++ b/src/uvw/loop.h | |
+@@ -14,6 +14,9 @@ | |
+ #include <uv.h> | |
+ #include "emitter.h" | |
+ #include "util.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -45,7 +48,7 @@ enum class UVRunMode: std::underlying_type_t<uv_run_mode> { | |
+ * users walk them as untyped instances.<br/> | |
+ * This can help to end all the pending requests by closing the handles. | |
+ */ | |
+-struct BaseHandle { | |
++struct UVW_EXTERN BaseHandle { | |
+ /** | |
+ * @brief Gets the category of the handle. | |
+ * | |
+@@ -140,7 +143,7 @@ struct BaseHandle { | |
+ * It takes care of polling for I/O and scheduling callbacks to be run based on | |
+ * different sources of events. | |
+ */ | |
+-class Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop> { | |
++class UVW_EXTERN Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop> { | |
+ using Deleter = void(*)(uv_loop_t *); | |
+ | |
+ template<typename, typename> | |
+@@ -425,9 +428,9 @@ class Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop | |
+ | |
+ // (extern) explicit instantiations | |
+ | |
+-extern template bool Loop::run<Loop::Mode::DEFAULT>() noexcept; | |
+-extern template bool Loop::run<Loop::Mode::ONCE>() noexcept; | |
+-extern template bool Loop::run<Loop::Mode::NOWAIT>() noexcept; | |
++extern template UVW_EXTERN bool Loop::run<Loop::Mode::DEFAULT>() noexcept; | |
++extern template UVW_EXTERN bool Loop::run<Loop::Mode::ONCE>() noexcept; | |
++extern template UVW_EXTERN bool Loop::run<Loop::Mode::NOWAIT>() noexcept; | |
+ | |
+ | |
+ } | |
+@@ -437,4 +440,6 @@ extern template bool Loop::run<Loop::Mode::NOWAIT>() noexcept; | |
+ #include "loop.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_LOOP_INCLUDE_H | |
+diff --git a/src/uvw/pipe.h b/src/uvw/pipe.h | |
+index d37ea40..c71c9dc 100644 | |
+--- a/src/uvw/pipe.h | |
++++ b/src/uvw/pipe.h | |
+@@ -10,6 +10,9 @@ | |
+ #include "stream.h" | |
+ #include "util.h" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -38,7 +41,7 @@ enum class UVChmodFlags: std::underlying_type_t<uv_poll_event> { | |
+ * * An optional boolean value that indicates if this pipe will be used for | |
+ * handle passing between processes. | |
+ */ | |
+-class PipeHandle final: public StreamHandle<PipeHandle, uv_pipe_t> { | |
++class UVW_EXTERN PipeHandle final: public StreamHandle<PipeHandle, uv_pipe_t> { | |
+ public: | |
+ using Chmod = details::UVChmodFlags; | |
+ | |
+@@ -164,4 +167,6 @@ class PipeHandle final: public StreamHandle<PipeHandle, uv_pipe_t> { | |
+ #include "pipe.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_PIPE_INCLUDE_H | |
+diff --git a/src/uvw/poll.h b/src/uvw/poll.h | |
+index 6030fd5..f12a25f 100644 | |
+--- a/src/uvw/poll.h | |
++++ b/src/uvw/poll.h | |
+@@ -7,6 +7,9 @@ | |
+ #include <uv.h> | |
+ #include "handle.hpp" | |
+ #include "util.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -31,7 +34,7 @@ enum class UVPollEvent: std::underlying_type_t<uv_poll_event> { | |
+ * | |
+ * It will be emitted by PollHandle according with its functionalities. | |
+ */ | |
+-struct PollEvent { | |
++struct UVW_EXTERN PollEvent { | |
+ explicit PollEvent(Flags<details::UVPollEvent> events) noexcept; | |
+ | |
+ /** | |
+@@ -46,6 +49,7 @@ struct PollEvent { | |
+ */ | |
+ Flags<details::UVPollEvent> flags; | |
+ }; | |
++template class UVW_EXTERN Flags<details::UVPollEvent>; | |
+ | |
+ | |
+ /** | |
+@@ -64,7 +68,7 @@ struct PollEvent { | |
+ * [documentation](http://docs.libuv.org/en/v1.x/poll.html) | |
+ * for further details. | |
+ */ | |
+-class PollHandle final: public Handle<PollHandle, uv_poll_t> { | |
++class UVW_EXTERN PollHandle final: public Handle<PollHandle, uv_poll_t> { | |
+ static void startCallback(uv_poll_t *handle, int status, int events); | |
+ | |
+ public: | |
+@@ -142,4 +146,6 @@ class PollHandle final: public Handle<PollHandle, uv_poll_t> { | |
+ #include "poll.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_POLL_INCLUDE_H | |
+diff --git a/src/uvw/prepare.h b/src/uvw/prepare.h | |
+index 736c7b8..9aab6e2 100644 | |
+--- a/src/uvw/prepare.h | |
++++ b/src/uvw/prepare.h | |
+@@ -5,6 +5,9 @@ | |
+ #include <uv.h> | |
+ #include "handle.hpp" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -15,7 +18,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by PrepareHandle according with its functionalities. | |
+ */ | |
+-struct PrepareEvent {}; | |
++struct UVW_EXTERN PrepareEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -26,7 +29,7 @@ struct PrepareEvent {}; | |
+ * | |
+ * To create a `PrepareHandle` through a `Loop`, no arguments are required. | |
+ */ | |
+-class PrepareHandle final: public Handle<PrepareHandle, uv_prepare_t> { | |
++class UVW_EXTERN PrepareHandle final: public Handle<PrepareHandle, uv_prepare_t> { | |
+ static void startCallback(uv_prepare_t *handle); | |
+ | |
+ public: | |
+@@ -62,4 +65,6 @@ class PrepareHandle final: public Handle<PrepareHandle, uv_prepare_t> { | |
+ #include "prepare.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_PREPARE_INCLUDE_H | |
+diff --git a/src/uvw/process.h b/src/uvw/process.h | |
+index f19fcc4..378a934 100644 | |
+--- a/src/uvw/process.h | |
++++ b/src/uvw/process.h | |
+@@ -11,6 +11,9 @@ | |
+ #include "stream.h" | |
+ #include "util.h" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -49,7 +52,7 @@ enum class UVStdIOFlags: std::underlying_type_t<uv_stdio_flags> { | |
+ * | |
+ * It will be emitted by ProcessHandle according with its functionalities. | |
+ */ | |
+-struct ExitEvent { | |
++struct UVW_EXTERN ExitEvent { | |
+ explicit ExitEvent(int64_t code, int sig) noexcept; | |
+ | |
+ int64_t status; /*!< The exit status. */ | |
+@@ -62,7 +65,7 @@ struct ExitEvent { | |
+ * Process handles will spawn a new process and allow the user to control it and | |
+ * establish communication channels with it using streams. | |
+ */ | |
+-class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> { | |
++class UVW_EXTERN ProcessHandle final: public Handle<ProcessHandle, uv_process_t> { | |
+ static void exitCallback(uv_process_t *handle, int64_t exitStatus, int termSignal); | |
+ | |
+ public: | |
+@@ -242,6 +245,7 @@ class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> { | |
+ Uid poUid; | |
+ Gid poGid; | |
+ }; | |
++template class UVW_EXTERN Flags<ProcessHandle::Process>; | |
+ | |
+ | |
+ } | |
+@@ -251,4 +255,6 @@ class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> { | |
+ #include "process.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_PROCESS_INCLUDE_H | |
+diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp | |
+index 212ad39..2dd773d 100644 | |
+--- a/src/uvw/request.hpp | |
++++ b/src/uvw/request.hpp | |
+@@ -7,6 +7,9 @@ | |
+ #include <memory> | |
+ #include <uv.h> | |
+ #include "resource.hpp" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -72,4 +75,6 @@ class Request: public Resource<T, U> { | |
+ | |
+ } | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_REQUEST_INCLUDE_H | |
+diff --git a/src/uvw/resource.hpp b/src/uvw/resource.hpp | |
+index 53c8adb..4f6d4ed 100644 | |
+--- a/src/uvw/resource.hpp | |
++++ b/src/uvw/resource.hpp | |
+@@ -6,6 +6,9 @@ | |
+ #include <utility> | |
+ #include "emitter.h" | |
+ #include "underlying_type.hpp" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -70,4 +73,6 @@ class Resource: public UnderlyingType<T, U>, public Emitter<T>, public std::enab | |
+ | |
+ } | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_RESOURCE_INCLUDE_H | |
+diff --git a/src/uvw/signal.h b/src/uvw/signal.h | |
+index 93b6905..d357d14 100644 | |
+--- a/src/uvw/signal.h | |
++++ b/src/uvw/signal.h | |
+@@ -5,6 +5,9 @@ | |
+ #include <uv.h> | |
+ #include "handle.hpp" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -15,7 +18,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by SignalHandle according with its functionalities. | |
+ */ | |
+-struct SignalEvent { | |
++struct UVW_EXTERN SignalEvent { | |
+ explicit SignalEvent(int sig) noexcept; | |
+ | |
+ int signum; /*!< The signal being monitored by this handle. */ | |
+@@ -35,7 +38,7 @@ struct SignalEvent { | |
+ * [documentation](http://docs.libuv.org/en/v1.x/signal.html) | |
+ * for further details. | |
+ */ | |
+-class SignalHandle final: public Handle<SignalHandle, uv_signal_t> { | |
++class UVW_EXTERN SignalHandle final: public Handle<SignalHandle, uv_signal_t> { | |
+ static void startCallback(uv_signal_t *handle, int signum); | |
+ | |
+ public: | |
+@@ -86,4 +89,6 @@ class SignalHandle final: public Handle<SignalHandle, uv_signal_t> { | |
+ #include "signal.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_SIGNAL_INCLUDE_H | |
+diff --git a/src/uvw/stream.h b/src/uvw/stream.h | |
+index 88d6dc1..d8be7b0 100644 | |
+--- a/src/uvw/stream.h | |
++++ b/src/uvw/stream.h | |
+@@ -11,6 +11,9 @@ | |
+ #include "request.hpp" | |
+ #include "handle.hpp" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -21,7 +24,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by StreamHandle according with its functionalities. | |
+ */ | |
+-struct ConnectEvent {}; | |
++struct UVW_EXTERN ConnectEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -29,7 +32,7 @@ struct ConnectEvent {}; | |
+ * | |
+ * It will be emitted by StreamHandle according with its functionalities. | |
+ */ | |
+-struct EndEvent {}; | |
++struct UVW_EXTERN EndEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -37,7 +40,7 @@ struct EndEvent {}; | |
+ * | |
+ * It will be emitted by StreamHandle according with its functionalities. | |
+ */ | |
+-struct ListenEvent {}; | |
++struct UVW_EXTERN ListenEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -45,7 +48,7 @@ struct ListenEvent {}; | |
+ * | |
+ * It will be emitted by StreamHandle according with its functionalities. | |
+ */ | |
+-struct ShutdownEvent {}; | |
++struct UVW_EXTERN ShutdownEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -53,7 +56,7 @@ struct ShutdownEvent {}; | |
+ * | |
+ * It will be emitted by StreamHandle according with its functionalities. | |
+ */ | |
+-struct WriteEvent {}; | |
++struct UVW_EXTERN WriteEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -61,7 +64,7 @@ struct WriteEvent {}; | |
+ * | |
+ * It will be emitted by StreamHandle according with its functionalities. | |
+ */ | |
+-struct DataEvent { | |
++struct UVW_EXTERN DataEvent { | |
+ explicit DataEvent(std::unique_ptr<char[]> buf, std::size_t len) noexcept; | |
+ | |
+ std::unique_ptr<char[]> data; /*!< A bunch of data read on the stream. */ | |
+@@ -82,7 +85,7 @@ struct ConnectReq final: public Request<ConnectReq, uv_connect_t> { | |
+ }; | |
+ | |
+ | |
+-struct ShutdownReq final: public Request<ShutdownReq, uv_shutdown_t> { | |
++struct UVW_EXTERN ShutdownReq final: public Request<ShutdownReq, uv_shutdown_t> { | |
+ using Request::Request; | |
+ | |
+ void shutdown(uv_stream_t *handle); | |
+@@ -447,4 +450,6 @@ class StreamHandle: public Handle<T, U> { | |
+ #include "stream.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_STREAM_INCLUDE_H | |
+diff --git a/src/uvw/tcp.h b/src/uvw/tcp.h | |
+index 2b1e255..30b4a90 100644 | |
+--- a/src/uvw/tcp.h | |
++++ b/src/uvw/tcp.h | |
+@@ -11,6 +11,9 @@ | |
+ #include "request.hpp" | |
+ #include "stream.h" | |
+ #include "util.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -43,7 +46,7 @@ enum class UVTCPFlags: std::underlying_type_t<uv_tcp_flags> { | |
+ * [documentation](http://docs.libuv.org/en/v1.x/tcp.html#c.uv_tcp_init_ex) | |
+ * for further details. | |
+ */ | |
+-class TCPHandle final: public StreamHandle<TCPHandle, uv_tcp_t> { | |
++class UVW_EXTERN TCPHandle final: public StreamHandle<TCPHandle, uv_tcp_t> { | |
+ public: | |
+ using Time = std::chrono::duration<unsigned int>; | |
+ using Bind = details::UVTCPFlags; | |
+@@ -232,23 +235,23 @@ class TCPHandle final: public StreamHandle<TCPHandle, uv_tcp_t> { | |
+ | |
+ // (extern) explicit instantiations | |
+ | |
+-extern template void TCPHandle::bind<IPv4>(std::string, unsigned int, Flags<Bind>); | |
+-extern template void TCPHandle::bind<IPv6>(std::string, unsigned int, Flags<Bind>); | |
++extern template UVW_EXTERN void TCPHandle::bind<IPv4>(std::string, unsigned int, Flags<Bind>); | |
++extern template UVW_EXTERN void TCPHandle::bind<IPv6>(std::string, unsigned int, Flags<Bind>); | |
+ | |
+-extern template void TCPHandle::bind<IPv4>(Addr, Flags<Bind>); | |
+-extern template void TCPHandle::bind<IPv6>(Addr, Flags<Bind>); | |
++extern template UVW_EXTERN void TCPHandle::bind<IPv4>(Addr, Flags<Bind>); | |
++extern template UVW_EXTERN void TCPHandle::bind<IPv6>(Addr, Flags<Bind>); | |
+ | |
+-extern template Addr TCPHandle::sock<IPv4>() const noexcept; | |
+-extern template Addr TCPHandle::sock<IPv6>() const noexcept; | |
++extern template UVW_EXTERN Addr TCPHandle::sock<IPv4>() const noexcept; | |
++extern template UVW_EXTERN Addr TCPHandle::sock<IPv6>() const noexcept; | |
+ | |
+-extern template Addr TCPHandle::peer<IPv4>() const noexcept; | |
+-extern template Addr TCPHandle::peer<IPv6>() const noexcept; | |
++extern template UVW_EXTERN Addr TCPHandle::peer<IPv4>() const noexcept; | |
++extern template UVW_EXTERN Addr TCPHandle::peer<IPv6>() const noexcept; | |
+ | |
+-extern template void TCPHandle::connect<IPv4>(std::string, unsigned int); | |
+-extern template void TCPHandle::connect<IPv6>(std::string, unsigned int); | |
++extern template UVW_EXTERN void TCPHandle::connect<IPv4>(std::string, unsigned int); | |
++extern template UVW_EXTERN void TCPHandle::connect<IPv6>(std::string, unsigned int); | |
+ | |
+-extern template void TCPHandle::connect<IPv4>(Addr addr); | |
+-extern template void TCPHandle::connect<IPv6>(Addr addr); | |
++extern template UVW_EXTERN void TCPHandle::connect<IPv4>(Addr addr); | |
++extern template UVW_EXTERN void TCPHandle::connect<IPv6>(Addr addr); | |
+ | |
+ | |
+ } | |
+@@ -258,4 +261,6 @@ extern template void TCPHandle::connect<IPv6>(Addr addr); | |
+ #include "tcp.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_TCP_INCLUDE_H | |
+diff --git a/src/uvw/thread.h b/src/uvw/thread.h | |
+index 912d8a1..07481d3 100644 | |
+--- a/src/uvw/thread.h | |
++++ b/src/uvw/thread.h | |
+@@ -10,6 +10,9 @@ | |
+ #include <uv.h> | |
+ #include "loop.h" | |
+ #include "underlying_type.hpp" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -46,7 +49,7 @@ class Barrier; | |
+ * that it can be assigned to an `std::function<void(std::shared_ptr<void>)>`. | |
+ * * An optional payload the type of which is `std::shared_ptr<void>`. | |
+ */ | |
+-class Thread final: public UnderlyingType<Thread, uv_thread_t> { | |
++class UVW_EXTERN Thread final: public UnderlyingType<Thread, uv_thread_t> { | |
+ using InternalTask = std::function<void(std::shared_ptr<void>)>; | |
+ | |
+ static void createCallback(void *arg); | |
+@@ -114,7 +117,7 @@ class Thread final: public UnderlyingType<Thread, uv_thread_t> { | |
+ * seen as a global variable that is only visible to a particular thread and not | |
+ * the whole program. | |
+ */ | |
+-class ThreadLocalStorage final: public UnderlyingType<ThreadLocalStorage, uv_key_t> { | |
++class UVW_EXTERN ThreadLocalStorage final: public UnderlyingType<ThreadLocalStorage, uv_key_t> { | |
+ public: | |
+ explicit ThreadLocalStorage(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept; | |
+ | |
+@@ -148,7 +151,7 @@ class ThreadLocalStorage final: public UnderlyingType<ThreadLocalStorage, uv_key | |
+ * Runs a function once and only once. Concurrent calls to `once` will block all | |
+ * callers except one (it’s unspecified which one). | |
+ */ | |
+-class Once final: public UnderlyingType<Once, uv_once_t> { | |
++class UVW_EXTERN Once final: public UnderlyingType<Once, uv_once_t> { | |
+ static uv_once_t* guard() noexcept; | |
+ | |
+ public: | |
+@@ -181,7 +184,7 @@ class Once final: public UnderlyingType<Once, uv_once_t> { | |
+ * * An option boolean that specifies if the mutex is a recursive one. The | |
+ * default value is false, the mutex isn't recursive. | |
+ */ | |
+-class Mutex final: public UnderlyingType<Mutex, uv_mutex_t> { | |
++class UVW_EXTERN Mutex final: public UnderlyingType<Mutex, uv_mutex_t> { | |
+ friend class Condition; | |
+ | |
+ public: | |
+@@ -210,7 +213,7 @@ class Mutex final: public UnderlyingType<Mutex, uv_mutex_t> { | |
+ /** | |
+ * @brief The RWLock wrapper. | |
+ */ | |
+-class RWLock final: public UnderlyingType<RWLock, uv_rwlock_t> { | |
++class UVW_EXTERN RWLock final: public UnderlyingType<RWLock, uv_rwlock_t> { | |
+ public: | |
+ explicit RWLock(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept; | |
+ | |
+@@ -257,7 +260,7 @@ class RWLock final: public UnderlyingType<RWLock, uv_rwlock_t> { | |
+ * | |
+ * * An unsigned integer that specifies the initial value for the semaphore. | |
+ */ | |
+-class Semaphore final: public UnderlyingType<Semaphore, uv_sem_t> { | |
++class UVW_EXTERN Semaphore final: public UnderlyingType<Semaphore, uv_sem_t> { | |
+ public: | |
+ explicit Semaphore(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int value) noexcept; | |
+ | |
+@@ -284,7 +287,7 @@ class Semaphore final: public UnderlyingType<Semaphore, uv_sem_t> { | |
+ /** | |
+ * @brief The Condition wrapper. | |
+ */ | |
+-class Condition final: public UnderlyingType<Condition, uv_cond_t> { | |
++class UVW_EXTERN Condition final: public UnderlyingType<Condition, uv_cond_t> { | |
+ public: | |
+ explicit Condition(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept; | |
+ | |
+@@ -344,7 +347,7 @@ class Condition final: public UnderlyingType<Condition, uv_cond_t> { | |
+ * `wait` before any of them successfully return from the call. The value | |
+ * specified must be greater than zero. | |
+ */ | |
+-class Barrier final: public UnderlyingType<Barrier, uv_barrier_t> { | |
++class UVW_EXTERN Barrier final: public UnderlyingType<Barrier, uv_barrier_t> { | |
+ public: | |
+ explicit Barrier(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int count) noexcept; | |
+ | |
+@@ -365,4 +368,6 @@ class Barrier final: public UnderlyingType<Barrier, uv_barrier_t> { | |
+ #include "thread.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_THREAD_INCLUDE_H | |
+diff --git a/src/uvw/timer.h b/src/uvw/timer.h | |
+index b1fbb43..443de0e 100644 | |
+--- a/src/uvw/timer.h | |
++++ b/src/uvw/timer.h | |
+@@ -6,6 +6,9 @@ | |
+ #include <uv.h> | |
+ #include "handle.hpp" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -16,7 +19,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by TimerHandle according with its functionalities. | |
+ */ | |
+-struct TimerEvent {}; | |
++struct UVW_EXTERN TimerEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -26,7 +29,7 @@ struct TimerEvent {}; | |
+ * | |
+ * To create a `TimerHandle` through a `Loop`, no arguments are required. | |
+ */ | |
+-class TimerHandle final: public Handle<TimerHandle, uv_timer_t> { | |
++class UVW_EXTERN TimerHandle final: public Handle<TimerHandle, uv_timer_t> { | |
+ static void startCallback(uv_timer_t *handle); | |
+ | |
+ public: | |
+@@ -104,4 +107,6 @@ class TimerHandle final: public Handle<TimerHandle, uv_timer_t> { | |
+ #include "timer.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_TIMER_INCLUDE_H | |
+diff --git a/src/uvw/tty.h b/src/uvw/tty.h | |
+index bbfb1ff..9b283cd 100644 | |
+--- a/src/uvw/tty.h | |
++++ b/src/uvw/tty.h | |
+@@ -7,6 +7,9 @@ | |
+ #include <uv.h> | |
+ #include "stream.h" | |
+ #include "util.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -15,7 +18,7 @@ namespace uvw { | |
+ namespace details { | |
+ | |
+ | |
+-struct ResetModeMemo { | |
++struct UVW_EXTERN ResetModeMemo { | |
+ ~ResetModeMemo(); | |
+ }; | |
+ | |
+@@ -54,7 +57,7 @@ enum class UVTTYVTermStateT: std::underlying_type_t<uv_tty_vtermstate_t> { | |
+ * [documentation](http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_init) | |
+ * for further details. | |
+ */ | |
+-class TTYHandle final: public StreamHandle<TTYHandle, uv_tty_t> { | |
++class UVW_EXTERN TTYHandle final: public StreamHandle<TTYHandle, uv_tty_t> { | |
+ static std::shared_ptr<details::ResetModeMemo> resetModeMemo(); | |
+ | |
+ public: | |
+@@ -152,4 +155,6 @@ class TTYHandle final: public StreamHandle<TTYHandle, uv_tty_t> { | |
+ #include "tty.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_TTY_INCLUDE_H | |
+diff --git a/src/uvw/udp.h b/src/uvw/udp.h | |
+index 68769a8..3251b02 100644 | |
+--- a/src/uvw/udp.h | |
++++ b/src/uvw/udp.h | |
+@@ -11,6 +11,9 @@ | |
+ #include "request.hpp" | |
+ #include "handle.hpp" | |
+ #include "util.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -21,7 +24,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by UDPHandle according with its functionalities. | |
+ */ | |
+-struct SendEvent {}; | |
++struct UVW_EXTERN SendEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -29,7 +32,7 @@ struct SendEvent {}; | |
+ * | |
+ * It will be emitted by UDPHandle according with its functionalities. | |
+ */ | |
+-struct UDPDataEvent { | |
++struct UVW_EXTERN UDPDataEvent { | |
+ explicit UDPDataEvent(Addr sndr, std::unique_ptr<const char[]> buf, std::size_t len, bool part) noexcept; | |
+ | |
+ std::unique_ptr<const char[]> data; /*!< A bunch of data read on the stream. */ | |
+@@ -57,7 +60,7 @@ enum class UVMembership: std::underlying_type_t<uv_membership> { | |
+ }; | |
+ | |
+ | |
+-class SendReq final: public Request<SendReq, uv_udp_send_t> { | |
++class UVW_EXTERN SendReq final: public Request<SendReq, uv_udp_send_t> { | |
+ public: | |
+ using Deleter = void(*)(char *); | |
+ | |
+@@ -90,7 +93,7 @@ class SendReq final: public Request<SendReq, uv_udp_send_t> { | |
+ * [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_init_ex) | |
+ * for further details. | |
+ */ | |
+-class UDPHandle final: public Handle<UDPHandle, uv_udp_t> { | |
++class UVW_EXTERN UDPHandle final: public Handle<UDPHandle, uv_udp_t> { | |
+ template<typename I> | |
+ static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) { | |
+ const typename details::IpTraits<I>::Type *aptr = reinterpret_cast<const typename details::IpTraits<I>::Type *>(addr); | |
+@@ -578,62 +581,62 @@ class UDPHandle final: public Handle<UDPHandle, uv_udp_t> { | |
+ | |
+ // (extern) explicit instantiations | |
+ | |
+-extern template void UDPHandle::connect<IPv4>(std::string, unsigned int); | |
+-extern template void UDPHandle::connect<IPv6>(std::string, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::connect<IPv4>(std::string, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::connect<IPv6>(std::string, unsigned int); | |
+ | |
+-extern template void UDPHandle::connect<IPv4>(Addr); | |
+-extern template void UDPHandle::connect<IPv6>(Addr); | |
++extern template UVW_EXTERN void UDPHandle::connect<IPv4>(Addr); | |
++extern template UVW_EXTERN void UDPHandle::connect<IPv6>(Addr); | |
+ | |
+-extern template Addr UDPHandle::peer<IPv4>() const noexcept; | |
+-extern template Addr UDPHandle::peer<IPv6>() const noexcept; | |
++extern template UVW_EXTERN Addr UDPHandle::peer<IPv4>() const noexcept; | |
++extern template UVW_EXTERN Addr UDPHandle::peer<IPv6>() const noexcept; | |
+ | |
+-extern template void UDPHandle::bind<IPv4>(std::string, unsigned int, Flags<Bind>); | |
+-extern template void UDPHandle::bind<IPv6>(std::string, unsigned int, Flags<Bind>); | |
++extern template UVW_EXTERN void UDPHandle::bind<IPv4>(std::string, unsigned int, Flags<Bind>); | |
++extern template UVW_EXTERN void UDPHandle::bind<IPv6>(std::string, unsigned int, Flags<Bind>); | |
+ | |
+-extern template void UDPHandle::bind<IPv4>(Addr, Flags<Bind>); | |
+-extern template void UDPHandle::bind<IPv6>(Addr, Flags<Bind>); | |
++extern template UVW_EXTERN void UDPHandle::bind<IPv4>(Addr, Flags<Bind>); | |
++extern template UVW_EXTERN void UDPHandle::bind<IPv6>(Addr, Flags<Bind>); | |
+ | |
+-extern template Addr UDPHandle::sock<IPv4>() const noexcept; | |
+-extern template Addr UDPHandle::sock<IPv6>() const noexcept; | |
++extern template UVW_EXTERN Addr UDPHandle::sock<IPv4>() const noexcept; | |
++extern template UVW_EXTERN Addr UDPHandle::sock<IPv6>() const noexcept; | |
+ | |
+-extern template bool UDPHandle::multicastMembership<IPv4>(std::string, std::string, Membership); | |
+-extern template bool UDPHandle::multicastMembership<IPv6>(std::string, std::string, Membership); | |
++extern template UVW_EXTERN bool UDPHandle::multicastMembership<IPv4>(std::string, std::string, Membership); | |
++extern template UVW_EXTERN bool UDPHandle::multicastMembership<IPv6>(std::string, std::string, Membership); | |
+ | |
+-extern template bool UDPHandle::multicastInterface<IPv4>(std::string); | |
+-extern template bool UDPHandle::multicastInterface<IPv6>(std::string); | |
++extern template UVW_EXTERN bool UDPHandle::multicastInterface<IPv4>(std::string); | |
++extern template UVW_EXTERN bool UDPHandle::multicastInterface<IPv6>(std::string); | |
+ | |
+-extern template void UDPHandle::send<IPv4>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
+-extern template void UDPHandle::send<IPv6>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::send<IPv4>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::send<IPv6>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
+ | |
+-extern template void UDPHandle::send<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int); | |
+-extern template void UDPHandle::send<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::send<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::send<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int); | |
+ | |
+-extern template void UDPHandle::send<IPv4>(std::string, unsigned int, char *, unsigned int); | |
+-extern template void UDPHandle::send<IPv6>(std::string, unsigned int, char *, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::send<IPv4>(std::string, unsigned int, char *, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::send<IPv6>(std::string, unsigned int, char *, unsigned int); | |
+ | |
+-extern template void UDPHandle::send<IPv4>(Addr, char *, unsigned int); | |
+-extern template void UDPHandle::send<IPv6>(Addr, char *, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::send<IPv4>(Addr, char *, unsigned int); | |
++extern template UVW_EXTERN void UDPHandle::send<IPv6>(Addr, char *, unsigned int); | |
+ | |
+-extern template int UDPHandle::trySend<IPv4>(const sockaddr &, std::unique_ptr<char[]>, unsigned int); | |
+-extern template int UDPHandle::trySend<IPv6>(const sockaddr &, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(const sockaddr &, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(const sockaddr &, std::unique_ptr<char[]>, unsigned int); | |
+ | |
+-extern template int UDPHandle::trySend<IPv4>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
+-extern template int UDPHandle::trySend<IPv6>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
+ | |
+-extern template int UDPHandle::trySend<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int); | |
+-extern template int UDPHandle::trySend<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int); | |
+ | |
+-extern template int UDPHandle::trySend<IPv4>(const sockaddr &, char *, unsigned int); | |
+-extern template int UDPHandle::trySend<IPv6>(const sockaddr &, char *, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(const sockaddr &, char *, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(const sockaddr &, char *, unsigned int); | |
+ | |
+-extern template int UDPHandle::trySend<IPv4>(std::string, unsigned int, char *, unsigned int); | |
+-extern template int UDPHandle::trySend<IPv6>(std::string, unsigned int, char *, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(std::string, unsigned int, char *, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(std::string, unsigned int, char *, unsigned int); | |
+ | |
+-extern template int UDPHandle::trySend<IPv4>(Addr, char *, unsigned int); | |
+-extern template int UDPHandle::trySend<IPv6>(Addr, char *, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(Addr, char *, unsigned int); | |
++extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(Addr, char *, unsigned int); | |
+ | |
+-extern template void UDPHandle::recv<IPv4>(); | |
+-extern template void UDPHandle::recv<IPv6>(); | |
++extern template UVW_EXTERN void UDPHandle::recv<IPv4>(); | |
++extern template UVW_EXTERN void UDPHandle::recv<IPv6>(); | |
+ | |
+ } | |
+ | |
+@@ -642,4 +645,6 @@ extern template void UDPHandle::recv<IPv6>(); | |
+ #include "udp.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_UDP_INCLUDE_H | |
+diff --git a/src/uvw/underlying_type.hpp b/src/uvw/underlying_type.hpp | |
+index 06c4a57..78cd5d7 100644 | |
+--- a/src/uvw/underlying_type.hpp | |
++++ b/src/uvw/underlying_type.hpp | |
+@@ -6,6 +6,9 @@ | |
+ #include <type_traits> | |
+ #include <utility> | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -116,4 +119,6 @@ class UnderlyingType { | |
+ | |
+ } | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_UNDERLYING_TYPE_INCLUDE_H | |
+diff --git a/src/uvw/util.cpp b/src/uvw/util.cpp | |
+index 95ef325..2f8a3a2 100644 | |
+--- a/src/uvw/util.cpp | |
++++ b/src/uvw/util.cpp | |
+@@ -69,6 +69,10 @@ UVW_INLINE std::string UtsName::machine() const noexcept { | |
+ return utsname ? utsname->machine : ""; | |
+ } | |
+ | |
++const details::IpTraits<IPv4>::AddrFuncType details::IpTraits<IPv4>::addrFunc = &uv_ip4_addr; | |
++const details::IpTraits<IPv4>::NameFuncType details::IpTraits<IPv4>::nameFunc = &uv_ip4_name; | |
++const details::IpTraits<IPv6>::AddrFuncType details::IpTraits<IPv6>::addrFunc = &uv_ip6_addr; | |
++const details::IpTraits<IPv6>::NameFuncType details::IpTraits<IPv6>::nameFunc = &uv_ip6_name; | |
+ | |
+ UVW_INLINE PidType Utilities::OS::pid() noexcept { | |
+ return uv_os_getpid(); | |
+diff --git a/src/uvw/util.h b/src/uvw/util.h | |
+index 4227137..93c7b34 100644 | |
+--- a/src/uvw/util.h | |
++++ b/src/uvw/util.h | |
+@@ -11,6 +11,9 @@ | |
+ #include <memory> | |
+ #include <array> | |
+ #include <uv.h> | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -177,7 +180,7 @@ class Flags final { | |
+ /** | |
+ * @brief Windows size representation. | |
+ */ | |
+-struct WinSize { | |
++struct UVW_EXTERN WinSize { | |
+ int width; /*!< The _width_ of the given window. */ | |
+ int height; /*!< The _height_ of the given window. */ | |
+ }; | |
+@@ -214,7 +217,7 @@ using RUsage = uv_rusage_t; /*!< Library equivalent for uv_rusage_t. */ | |
+ * | |
+ * \sa Utilities::passwd | |
+ */ | |
+-struct Passwd { | |
++struct UVW_EXTERN Passwd { | |
+ Passwd(std::shared_ptr<uv_passwd_t> pwd); | |
+ | |
+ /** | |
+@@ -267,7 +270,7 @@ struct Passwd { | |
+ * | |
+ * \sa Utilities::uname | |
+ */ | |
+-struct UtsName { | |
++struct UVW_EXTERN UtsName { | |
+ UtsName(std::shared_ptr<uv_utsname_t> utsname); | |
+ | |
+ /** | |
+@@ -304,7 +307,7 @@ struct UtsName { | |
+ * | |
+ * To be used as template parameter to switch between IPv4 and IPv6. | |
+ */ | |
+-struct IPv4 {}; | |
++struct UVW_EXTERN IPv4 {}; | |
+ | |
+ | |
+ /** | |
+@@ -312,13 +315,13 @@ struct IPv4 {}; | |
+ * | |
+ * To be used as template parameter to switch between IPv4 and IPv6. | |
+ */ | |
+-struct IPv6 {}; | |
++struct UVW_EXTERN IPv6 {}; | |
+ | |
+ | |
+ /** | |
+ * @brief Address representation. | |
+ */ | |
+-struct Addr { | |
++struct UVW_EXTERN Addr { | |
+ std::string ip; /*!< Either an IPv4 or an IPv6. */ | |
+ unsigned int port; /*!< A valid service identifier. */ | |
+ }; | |
+@@ -327,7 +330,7 @@ struct Addr { | |
+ /** | |
+ * \brief CPU information. | |
+ */ | |
+-struct CPUInfo { | |
++struct UVW_EXTERN CPUInfo { | |
+ using CPUTime = decltype(uv_cpu_info_t::cpu_times); | |
+ | |
+ std::string model; /*!< The model of the CPU. */ | |
+@@ -346,7 +349,7 @@ struct CPUInfo { | |
+ /** | |
+ * \brief Interface address. | |
+ */ | |
+-struct InterfaceAddress { | |
++struct UVW_EXTERN InterfaceAddress { | |
+ std::string name; /*!< The name of the interface (as an example _eth0_). */ | |
+ char physical[6]; /*!< The physical address. */ | |
+ bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */ | |
+@@ -364,14 +367,13 @@ static constexpr std::size_t DEFAULT_SIZE = 128; | |
+ template<typename> | |
+ struct IpTraits; | |
+ | |
+- | |
+ template<> | |
+ struct IpTraits<IPv4> { | |
+ using Type = sockaddr_in; | |
+- using AddrFuncType = int(*)(const char *, int, Type *); | |
+- using NameFuncType = int(*)(const Type *, char *, std::size_t); | |
+- static constexpr AddrFuncType addrFunc = &uv_ip4_addr; | |
+- static constexpr NameFuncType nameFunc = &uv_ip4_name; | |
++ using AddrFuncType = int (*)(const char*, int, Type*); | |
++ using NameFuncType = int (*)(const Type*, char*, std::size_t); | |
++ static UVW_EXTERN const AddrFuncType addrFunc; | |
++ static UVW_EXTERN const NameFuncType nameFunc; | |
+ static constexpr auto sinPort(const Type *addr) { return addr->sin_port; } | |
+ }; | |
+ | |
+@@ -381,8 +383,8 @@ struct IpTraits<IPv6> { | |
+ using Type = sockaddr_in6; | |
+ using AddrFuncType = int(*)(const char *, int, Type *); | |
+ using NameFuncType = int(*)(const Type *, char *, std::size_t); | |
+- static constexpr AddrFuncType addrFunc = &uv_ip6_addr; | |
+- static constexpr NameFuncType nameFunc = &uv_ip6_name; | |
++ static UVW_EXTERN const AddrFuncType addrFunc; | |
++ static UVW_EXTERN const NameFuncType nameFunc; | |
+ static constexpr auto sinPort(const Type *addr) { return addr->sin6_port; } | |
+ }; | |
+ | |
+@@ -450,7 +452,7 @@ std::string tryRead(F &&f, Args&&... args) noexcept { | |
+ * | |
+ * Miscellaneous functions that don’t really belong to any other class. | |
+ */ | |
+-struct Utilities { | |
++struct UVW_EXTERN Utilities { | |
+ using MallocFuncType = void*(*)(size_t); | |
+ using ReallocFuncType = void*(*)(void*, size_t); | |
+ using CallocFuncType = void*(*)(size_t, size_t); | |
+@@ -459,7 +461,7 @@ struct Utilities { | |
+ /** | |
+ * @brief OS dedicated utilities. | |
+ */ | |
+- struct OS { | |
++ struct UVW_EXTERN OS { | |
+ /** | |
+ * @brief Returns the current process id. | |
+ * | |
+@@ -829,4 +831,6 @@ struct Utilities { | |
+ #include "util.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_UTIL_INCLUDE_H | |
+diff --git a/src/uvw/work.h b/src/uvw/work.h | |
+index 00cc86f..f5b9c3c 100644 | |
+--- a/src/uvw/work.h | |
++++ b/src/uvw/work.h | |
+@@ -7,6 +7,9 @@ | |
+ #include <uv.h> | |
+ #include "request.hpp" | |
+ #include "loop.h" | |
++#include "config.h" | |
++ | |
++UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
+ | |
+ namespace uvw { | |
+@@ -17,7 +20,7 @@ namespace uvw { | |
+ * | |
+ * It will be emitted by WorkReq according with its functionalities. | |
+ */ | |
+-struct WorkEvent {}; | |
++struct UVW_EXTERN WorkEvent {}; | |
+ | |
+ | |
+ /** | |
+@@ -34,7 +37,7 @@ struct WorkEvent {}; | |
+ * [documentation](http://docs.libuv.org/en/v1.x/threadpool.html) | |
+ * for further details. | |
+ */ | |
+-class WorkReq final: public Request<WorkReq, uv_work_t> { | |
++class UVW_EXTERN WorkReq final: public Request<WorkReq, uv_work_t> { | |
+ using InternalTask = std::function<void(void)>; | |
+ | |
+ static void workCallback(uv_work_t *req); | |
+@@ -65,4 +68,6 @@ class WorkReq final: public Request<WorkReq, uv_work_t> { | |
+ #include "work.cpp" | |
+ #endif | |
+ | |
++UVW_MSVC_WARNING_POP(); | |
++ | |
+ #endif // UVW_WORK_INCLUDE_H | |
+diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt | |
+index 8d0b3e7..672eb4b 100644 | |
+--- a/test/CMakeLists.txt | |
++++ b/test/CMakeLists.txt | |
+@@ -46,8 +46,8 @@ function(ADD_UVW_TEST TEST_NAME TEST_SOURCE) | |
+ ${TEST_NAME} | |
+ PRIVATE | |
+ $<$<TARGET_EXISTS:uvw::uvw>:uvw::uvw> | |
+- $<$<TARGET_EXISTS:uvw::uvw>:uv::uv-static> | |
+- $<$<TARGET_EXISTS:uvw::uvw-static>:uvw::uvw-static> | |
++ $<$<TARGET_EXISTS:uv::uv-shared>:uv::uv-shared> | |
++ $<$<TARGET_EXISTS:uvw::uvw-shared>:uvw::uvw-shared> | |
+ GTest::Main | |
+ Threads::Threads | |
+ ${LIBRT} | |
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt | |
index 25e6c12..ea1700a 100644 | |
--- a/src/CMakeLists.txt | |
+++ b/src/CMakeLists.txt | |
@@ -29,6 +29,7 @@ function(add_uvw_library LIB_NAME) | |
uvw/udp.cpp | |
uvw/util.cpp | |
uvw/work.cpp | |
+ uvw/type_factory/type_factory.cpp | |
) | |
set_target_properties(${LIB_NAME} PROPERTIES POSITION_INDEPENDENT_CODE 1) | |
@@ -74,8 +75,20 @@ add_uvw_library(uvw-static) | |
add_library(uvw-shared SHARED) | |
add_library(uvw::uvw-shared ALIAS uvw-shared) | |
target_link_libraries(uvw-shared PUBLIC uv::uv-shared) | |
-set_target_properties(uvw-shared PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${UVW_VERSION_MAJOR} EXCLUDE_FROM_DEFAULT_BUILD 1) | |
+set_target_properties(uvw-shared PROPERTIES | |
+ VERSION ${PROJECT_VERSION} | |
+ SOVERSION ${UVW_VERSION_MAJOR} | |
+ EXCLUDE_FROM_DEFAULT_BUILD 1 | |
+ C_VISIBILITY_PRESET hidden | |
+ CXX_VISIBILITY_PRESET hidden | |
+) | |
add_uvw_library(uvw-shared) | |
+target_compile_definitions(uvw-shared | |
+ INTERFACE | |
+ USING_UVW_SHARED=1 | |
+ PRIVATE | |
+ BUILDING_UVW_SHARED=1 | |
+) | |
# | |
# Install targets | |
diff --git a/src/uvw.hpp b/src/uvw.hpp | |
index aaf8f4c..c4ba5cf 100644 | |
--- a/src/uvw.hpp | |
+++ b/src/uvw.hpp | |
@@ -25,3 +25,244 @@ | |
#include "uvw/underlying_type.hpp" | |
#include "uvw/util.h" | |
#include "uvw/work.h" | |
+ | |
+namespace uvw { | |
+ extern template UVW_EXTERN std::size_t details::type_factory<IdleHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<IdleHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<IdleHandle>::event_type<IdleEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<AsyncHandle>::event_type<AsyncEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<AsyncHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<WorkReq>::event_type<WorkEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 1> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 2> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 3> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 4> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 5> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 6> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 7> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 8> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 9> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 10> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 11> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 12> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 13> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 14> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 15> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 16> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 17> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 18> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 19> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 20> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 21> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 22> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 23> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 24> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 25> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 26> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 27> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 28> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 29> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 30> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 31> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 32> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 33> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 34> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 35> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 36> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 37> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 38> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 39> >() noexcept; | |
+ | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<details::ShutdownReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 11> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<GetNameInfoReq>::event_type<NameInfoEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TimerHandle>::event_type<TimerEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<CheckHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 27> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<details::SendReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 9> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TCPHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<ProcessHandle>::event_type<ExitEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PrepareHandle>::event_type<PrepareEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TCPHandle>::event_type<ConnectEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsEventHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 15> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsEventHandle>::event_type<FsEventEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TimerHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TCPHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<GetNameInfoReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PrepareHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<WorkReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PollHandle>::event_type<PollEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PollHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<SignalHandle>::event_type<SignalEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PipeHandle>::event_type<ConnectEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<details::ShutdownReq>::event_type<ShutdownEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 5> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TTYHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<UDPHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<Loop>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<UDPHandle>::event_type<SendEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PipeHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsPollHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<GetAddrInfoReq>::event_type<AddrInfoEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<details::ConnectReq>::event_type<ConnectEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<UDPHandle>::event_type<UDPDataEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<details::ConnectReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 14> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsPollHandle>::event_type<FsPollEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 16> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<GetAddrInfoReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<UDPHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 1> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<details::SendReq>::event_type<SendEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<SignalHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 2> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 3> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 8> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 4> >() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<ProcessHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<ProcessHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TTYHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PollHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PipeHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<CheckHandle>::event_type<CheckEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<CheckHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<AsyncHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PrepareHandle>::event_type<CloseEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsEventHandle>::event_type<CloseEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FsPollHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TCPHandle>::event_type<WriteEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TCPHandle>::event_type<EndEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TCPHandle>::event_type<DataEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TCPHandle>::event_type<ListenEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TCPHandle>::event_type<ShutdownEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TTYHandle>::event_type<WriteEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PipeHandle>::event_type<WriteEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PipeHandle>::event_type<EndEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PipeHandle>::event_type<DataEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PipeHandle>::event_type<ListenEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<PipeHandle>::event_type<ShutdownEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<SignalHandle>::event_type<CheckEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<SignalHandle>::event_type<CloseEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FakeHandle>::event_type<CloseEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<FakeHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TestEmitter>::event_type<FakeEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<TestEmitter>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<WriteReq<std::default_delete<char []> > >::event_type<ErrorEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<WriteReq<std::default_delete<char []> > >::event_type<WriteEvent>() noexcept; | |
+ | |
+ extern template UVW_EXTERN std::size_t details::type_factory<WriteReq<void (*)(char*) > >::event_type<ErrorEvent>() noexcept; | |
+ extern template UVW_EXTERN std::size_t details::type_factory<WriteReq<void (*)(char*) > >::event_type<WriteEvent>() noexcept; | |
+} | |
diff --git a/src/uvw/async.h b/src/uvw/async.h | |
index e326bac..4e6f4e3 100644 | |
--- a/src/uvw/async.h | |
+++ b/src/uvw/async.h | |
@@ -5,7 +5,9 @@ | |
#include <uv.h> | |
#include "handle.hpp" | |
#include "loop.h" | |
+#include "config.h" | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -15,7 +17,7 @@ namespace uvw { | |
* | |
* It will be emitted by AsyncHandle according with its functionalities. | |
*/ | |
-struct AsyncEvent {}; | |
+struct UVW_EXTERN AsyncEvent {}; | |
/** | |
@@ -26,7 +28,7 @@ struct AsyncEvent {}; | |
* | |
* To create an `AsyncHandle` through a `Loop`, no arguments are required. | |
*/ | |
-class AsyncHandle final: public Handle<AsyncHandle, uv_async_t> { | |
+class UVW_EXTERN AsyncHandle final : public Handle<AsyncHandle, uv_async_t> { | |
static void sendCallback(uv_async_t *handle); | |
public: | |
@@ -63,4 +65,6 @@ class AsyncHandle final: public Handle<AsyncHandle, uv_async_t> { | |
#include "async.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_ASYNC_INCLUDE_H | |
diff --git a/src/uvw/check.h b/src/uvw/check.h | |
index 4d3e571..79f6d37 100644 | |
--- a/src/uvw/check.h | |
+++ b/src/uvw/check.h | |
@@ -5,7 +5,9 @@ | |
#include <uv.h> | |
#include "handle.hpp" | |
#include "loop.h" | |
+#include "config.h" | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -15,7 +17,7 @@ namespace uvw { | |
* | |
* It will be emitted by CheckHandle according with its functionalities. | |
*/ | |
-struct CheckEvent {}; | |
+struct UVW_EXTERN CheckEvent {}; | |
/** | |
@@ -26,7 +28,7 @@ struct CheckEvent {}; | |
* | |
* To create a `CheckHandle` through a `Loop`, no arguments are required. | |
*/ | |
-class CheckHandle final: public Handle<CheckHandle, uv_check_t> { | |
+class UVW_EXTERN CheckHandle final : public Handle<CheckHandle, uv_check_t> { | |
static void startCallback(uv_check_t *handle); | |
public: | |
@@ -60,4 +62,6 @@ class CheckHandle final: public Handle<CheckHandle, uv_check_t> { | |
#include "check.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_CHECK_INCLUDE_H | |
diff --git a/src/uvw/config.h b/src/uvw/config.h | |
index cfee0c9..429f8fe 100644 | |
--- a/src/uvw/config.h | |
+++ b/src/uvw/config.h | |
@@ -1,12 +1,48 @@ | |
#ifndef UVW_CONFIG_H | |
#define UVW_CONFIG_H | |
+#if defined(BUILDING_UVW_SHARED) && defined(USING_UVW_SHARED) | |
+#error "Define either BUILDING_UVW_SHARED or USING_UVW_SHARED, not both." | |
+#endif | |
#ifndef UVW_AS_LIB | |
#define UVW_INLINE inline | |
+#define UVW_EXTERN /* nothing */ | |
+#else /* UVW_AS_LIB */ | |
+#define UVW_INLINE /* nothing */ | |
+ | |
+#ifdef _WIN32 | |
+/* Windows - set up dll import/export decorators. */ | |
+#if defined(BUILDING_UVW_SHARED) | |
+/* Building shared library. */ | |
+#define UVW_EXTERN __declspec(dllexport) | |
+#elif defined(USING_UVW_SHARED) | |
+/* Using shared library. */ | |
+#define UVW_EXTERN __declspec(dllimport) | |
+#else | |
+/* Building static library. */ | |
+#define UVW_EXTERN /* nothing */ | |
+#endif | |
+#elif __GNUC__ >= 4 | |
+#define UVW_EXTERN __attribute__((visibility("default"))) | |
#else | |
-#define UVW_INLINE | |
+#define UVW_EXTERN /* nothing */ | |
#endif | |
+#endif /* UVW_AS_LIB */ | |
+ | |
+#if defined(_MSC_VER) && defined(UVW_AS_LIB) | |
+/* | |
+ * C4251: 'type' : class 'type1' needs to have dll-interface to be used by clients of class 'type2' | |
+ */ | |
+#define UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE() \ | |
+ __pragma(warning(push)) \ | |
+ __pragma(warning(disable: 4251)) | |
+#define UVW_MSVC_WARNING_POP() \ | |
+ __pragma(warning(pop)) | |
+#else | |
+#define UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE() | |
+#define UVW_MSVC_WARNING_POP() | |
+#endif | |
#endif | |
diff --git a/src/uvw/dns.h b/src/uvw/dns.h | |
index e9b2e86..db90ddd 100644 | |
--- a/src/uvw/dns.h | |
+++ b/src/uvw/dns.h | |
@@ -9,6 +9,9 @@ | |
#include "request.hpp" | |
#include "util.h" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -19,7 +22,7 @@ namespace uvw { | |
* | |
* It will be emitted by GetAddrInfoReq according with its functionalities. | |
*/ | |
-struct AddrInfoEvent { | |
+struct UVW_EXTERN AddrInfoEvent { | |
using Deleter = void(*)(addrinfo *); | |
AddrInfoEvent(std::unique_ptr<addrinfo, Deleter> addr); | |
@@ -39,7 +42,7 @@ struct AddrInfoEvent { | |
* | |
* It will be emitted by GetNameInfoReq according with its functionalities. | |
*/ | |
-struct NameInfoEvent { | |
+struct UVW_EXTERN NameInfoEvent { | |
NameInfoEvent(const char *host, const char *serv); | |
/** | |
@@ -68,7 +71,7 @@ struct NameInfoEvent { | |
* | |
* To create a `GetAddrInfoReq` through a `Loop`, no arguments are required. | |
*/ | |
-class GetAddrInfoReq final: public Request<GetAddrInfoReq, uv_getaddrinfo_t> { | |
+class UVW_EXTERN GetAddrInfoReq final: public Request<GetAddrInfoReq, uv_getaddrinfo_t> { | |
static void addrInfoCallback(uv_getaddrinfo_t *req, int status, addrinfo *res); | |
void nodeAddrInfo(const char *node, const char *service, addrinfo *hints = nullptr); | |
auto nodeAddrInfoSync(const char *node, const char *service, addrinfo *hints = nullptr); | |
@@ -153,7 +156,7 @@ class GetAddrInfoReq final: public Request<GetAddrInfoReq, uv_getaddrinfo_t> { | |
* | |
* To create a `GetNameInfoReq` through a `Loop`, no arguments are required. | |
*/ | |
-class GetNameInfoReq final: public Request<GetNameInfoReq, uv_getnameinfo_t> { | |
+class UVW_EXTERN GetNameInfoReq final: public Request<GetNameInfoReq, uv_getnameinfo_t> { | |
static void nameInfoCallback(uv_getnameinfo_t *req, int status, const char *hostname, const char *service); | |
public: | |
@@ -232,17 +235,17 @@ class GetNameInfoReq final: public Request<GetNameInfoReq, uv_getnameinfo_t> { | |
// (extern) explicit instantiations | |
-extern template void GetNameInfoReq::nameInfo<IPv4>(std::string ip, unsigned int port, int flags); | |
-extern template void GetNameInfoReq::nameInfo<IPv6>(std::string ip, unsigned int port, int flags); | |
+extern template UVW_EXTERN void GetNameInfoReq::nameInfo<IPv4>(std::string ip, unsigned int port, int flags); | |
+extern template UVW_EXTERN void GetNameInfoReq::nameInfo<IPv6>(std::string ip, unsigned int port, int flags); | |
-extern template void GetNameInfoReq::nameInfo<IPv4>(Addr addr, int flags); | |
-extern template void GetNameInfoReq::nameInfo<IPv6>(Addr addr, int flags); | |
+extern template UVW_EXTERN void GetNameInfoReq::nameInfo<IPv4>(Addr addr, int flags); | |
+extern template UVW_EXTERN void GetNameInfoReq::nameInfo<IPv6>(Addr addr, int flags); | |
-extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv4>(std::string ip, unsigned int port, int flags); | |
-extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(std::string ip, unsigned int port, int flags); | |
+extern template UVW_EXTERN std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv4>(std::string ip, unsigned int port, int flags); | |
+extern template UVW_EXTERN std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(std::string ip, unsigned int port, int flags); | |
-extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv4>(Addr addr, int flags); | |
-extern template std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(Addr addr, int flags); | |
+extern template UVW_EXTERN std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv4>(Addr addr, int flags); | |
+extern template UVW_EXTERN std::pair<bool, std::pair<const char *, const char *>> GetNameInfoReq::nameInfoSync<IPv6>(Addr addr, int flags); | |
} | |
@@ -252,4 +255,6 @@ extern template std::pair<bool, std::pair<const char *, const char *>> GetNameIn | |
#include "dns.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_DNS_INCLUDE_H | |
diff --git a/src/uvw/emitter.h b/src/uvw/emitter.h | |
index a189f3a..e7ade99 100644 | |
--- a/src/uvw/emitter.h | |
+++ b/src/uvw/emitter.h | |
@@ -12,6 +12,11 @@ | |
#include <list> | |
#include <uv.h> | |
+#include "config.h" | |
+#include "type_factory/type_factory.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
+ | |
namespace uvw { | |
@@ -21,7 +26,7 @@ namespace uvw { | |
* | |
* Custom wrapper around error constants of `libuv`. | |
*/ | |
-struct ErrorEvent { | |
+struct UVW_EXTERN ErrorEvent { | |
template<typename U, typename = std::enable_if_t<std::is_integral_v<U>>> | |
explicit ErrorEvent(U val) noexcept | |
: ec{static_cast<int>(val)} | |
@@ -157,20 +162,9 @@ class Emitter { | |
ListenerList onL{}; | |
}; | |
- static std::size_t next_type() noexcept { | |
- static std::size_t counter = 0; | |
- return counter++; | |
- } | |
- | |
- template<typename> | |
- static std::size_t event_type() noexcept { | |
- static std::size_t value = next_type(); | |
- return value; | |
- } | |
- | |
template<typename E> | |
Handler<E> & handler() noexcept { | |
- std::size_t type = event_type<E>(); | |
+ std::size_t type = details::type_factory<T>::template event_type<E>(); | |
if(!(type < handlers.size())) { | |
handlers.resize(type+1); | |
@@ -190,6 +184,14 @@ class Emitter { | |
} | |
public: | |
+ Emitter() = default; | |
+ Emitter(Emitter &&) = default; | |
+ Emitter & operator=(Emitter &&) = default; | |
+ | |
+ // These must be deleted because MSVC try to export them with UVW_EXPORT | |
+ Emitter(const Emitter&) = delete; | |
+ Emitter& operator=(const Emitter&) = delete; | |
+ | |
template<typename E> | |
using Listener = typename Handler<E>::Listener; | |
@@ -292,7 +294,7 @@ class Emitter { | |
*/ | |
template<typename E> | |
bool empty() const noexcept { | |
- std::size_t type = event_type<E>(); | |
+ std::size_t type = details::type_factory<T>::template event_type<E>(); | |
return (!(type < handlers.size()) || | |
!handlers[type] || | |
@@ -316,9 +318,16 @@ class Emitter { | |
} | |
+struct UVW_EXTERN FakeEvent { }; | |
+ | |
+struct UVW_EXTERN TestEmitter: uvw::Emitter<TestEmitter> { | |
+ void emit() { publish(FakeEvent{}); } | |
+}; | |
#ifndef UVW_AS_LIB | |
#include "emitter.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_EMITTER_INCLUDE_H | |
diff --git a/src/uvw/fs.h b/src/uvw/fs.h | |
index c4af1d4..d4a1ea1 100644 | |
--- a/src/uvw/fs.h | |
+++ b/src/uvw/fs.h | |
@@ -10,6 +10,9 @@ | |
#include "request.hpp" | |
#include "util.h" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -433,7 +436,7 @@ class FsRequest: public Request<T, uv_fs_t> { | |
* [documentation](http://docs.libuv.org/en/v1.x/fs.html) | |
* for further details. | |
*/ | |
-class FileReq final: public FsRequest<FileReq> { | |
+class UVW_EXTERN FileReq final: public FsRequest<FileReq> { | |
static constexpr uv_file BAD_FD = -1; | |
static void fsOpenCallback(uv_fs_t *req); | |
@@ -784,7 +787,7 @@ class FileReq final: public FsRequest<FileReq> { | |
* [documentation](http://docs.libuv.org/en/v1.x/fs.html) | |
* for further details. | |
*/ | |
-class FsReq final: public FsRequest<FsReq> { | |
+class UVW_EXTERN FsReq final: public FsRequest<FsReq> { | |
static void fsReadlinkCallback(uv_fs_t *req); | |
static void fsReaddirCallback(uv_fs_t *req); | |
@@ -1425,7 +1428,7 @@ class FsReq final: public FsRequest<FsReq> { | |
/*! @brief Helper functions. */ | |
-struct FsHelper { | |
+struct UVW_EXTERN FsHelper { | |
/** | |
* @brief Gets the OS dependent handle. | |
* | |
@@ -1459,4 +1462,6 @@ struct FsHelper { | |
#include "fs.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_FS_INCLUDE_H | |
diff --git a/src/uvw/fs_event.h b/src/uvw/fs_event.h | |
index 6cbc5a0..ba15842 100644 | |
--- a/src/uvw/fs_event.h | |
+++ b/src/uvw/fs_event.h | |
@@ -8,6 +8,9 @@ | |
#include "handle.hpp" | |
#include "util.h" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -37,7 +40,7 @@ enum class UVFsEvent: std::underlying_type_t<uv_fs_event> { | |
* | |
* It will be emitted by FsEventHandle according with its functionalities. | |
*/ | |
-struct FsEventEvent { | |
+struct UVW_EXTERN FsEventEvent { | |
FsEventEvent(const char * pathname, Flags<details::UVFsEvent> events); | |
/** | |
@@ -58,6 +61,7 @@ struct FsEventEvent { | |
*/ | |
Flags<details::UVFsEvent> flags; | |
}; | |
+template class UVW_EXTERN Flags<details::UVFsEvent>; | |
/** | |
@@ -73,7 +77,7 @@ struct FsEventEvent { | |
* [documentation](http://docs.libuv.org/en/v1.x/fs_event.html) | |
* for further details. | |
*/ | |
-class FsEventHandle final: public Handle<FsEventHandle, uv_fs_event_t> { | |
+class UVW_EXTERN FsEventHandle final: public Handle<FsEventHandle, uv_fs_event_t> { | |
static void startCallback(uv_fs_event_t *handle, const char *filename, int events, int status); | |
public: | |
@@ -146,4 +150,6 @@ class FsEventHandle final: public Handle<FsEventHandle, uv_fs_event_t> { | |
#include "fs_event.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_FS_EVENT_INCLUDE_H | |
diff --git a/src/uvw/fs_poll.h b/src/uvw/fs_poll.h | |
index a264eb3..365669b 100644 | |
--- a/src/uvw/fs_poll.h | |
+++ b/src/uvw/fs_poll.h | |
@@ -8,6 +8,9 @@ | |
#include "handle.hpp" | |
#include "util.h" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -18,7 +21,7 @@ namespace uvw { | |
* | |
* It will be emitted by FsPollHandle according with its functionalities. | |
*/ | |
-struct FsPollEvent { | |
+struct UVW_EXTERN FsPollEvent { | |
explicit FsPollEvent(Stat previous, Stat current) noexcept; | |
Stat prev; /*!< The old Stat struct. */ | |
@@ -35,7 +38,7 @@ struct FsPollEvent { | |
* | |
* To create a `FsPollHandle` through a `Loop`, no arguments are required. | |
*/ | |
-class FsPollHandle final: public Handle<FsPollHandle, uv_fs_poll_t> { | |
+class UVW_EXTERN FsPollHandle final: public Handle<FsPollHandle, uv_fs_poll_t> { | |
static void startCallback(uv_fs_poll_t *handle, int status, const uv_stat_t *prev, const uv_stat_t *curr); | |
public: | |
@@ -80,4 +83,6 @@ class FsPollHandle final: public Handle<FsPollHandle, uv_fs_poll_t> { | |
#include "fs_poll.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_FS_POLL_INCLUDE_H | |
diff --git a/src/uvw/handle.hpp b/src/uvw/handle.hpp | |
index 274f4fc..17d059c 100644 | |
--- a/src/uvw/handle.hpp | |
+++ b/src/uvw/handle.hpp | |
@@ -8,6 +8,9 @@ | |
#include <uv.h> | |
#include "resource.hpp" | |
#include "util.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -18,7 +21,7 @@ namespace uvw { | |
* | |
* It will be emitted by the handles according with their functionalities. | |
*/ | |
-struct CloseEvent {}; | |
+struct UVW_EXTERN CloseEvent {}; | |
/** | |
@@ -274,4 +277,15 @@ class Handle: public Resource<T, U>, public BaseHandle { | |
} | |
+struct fake_handle_t { void *data; }; | |
+ | |
+struct UVW_EXTERN FakeHandle: uvw::Handle<FakeHandle, fake_handle_t> { | |
+ using Handle::Handle; | |
+ | |
+ template<typename... Args> | |
+ bool init(Args&&...) { return initialize([](auto...){ return true; }); } | |
+}; | |
+ | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_HANDLE_INCLUDE_H | |
diff --git a/src/uvw/idle.h b/src/uvw/idle.h | |
index 28a8c12..af78ce1 100644 | |
--- a/src/uvw/idle.h | |
+++ b/src/uvw/idle.h | |
@@ -5,6 +5,9 @@ | |
#include <uv.h> | |
#include "handle.hpp" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -15,7 +18,7 @@ namespace uvw { | |
* | |
* It will be emitted by IdleHandle according with its functionalities. | |
*/ | |
-struct IdleEvent {}; | |
+struct UVW_EXTERN IdleEvent {}; | |
/** | |
@@ -34,7 +37,7 @@ struct IdleEvent {}; | |
* | |
* To create an `IdleHandle` through a `Loop`, no arguments are required. | |
*/ | |
-class IdleHandle final: public Handle<IdleHandle, uv_idle_t> { | |
+class UVW_EXTERN IdleHandle final: public Handle<IdleHandle, uv_idle_t> { | |
static void startCallback(uv_idle_t *handle); | |
public: | |
@@ -68,4 +71,6 @@ class IdleHandle final: public Handle<IdleHandle, uv_idle_t> { | |
#include "idle.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_IDLE_INCLUDE_H | |
diff --git a/src/uvw/lib.h b/src/uvw/lib.h | |
index 7e8fff1..b8e293d 100644 | |
--- a/src/uvw/lib.h | |
+++ b/src/uvw/lib.h | |
@@ -8,6 +8,9 @@ | |
#include <uv.h> | |
#include "loop.h" | |
#include "underlying_type.hpp" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -19,7 +22,7 @@ namespace uvw { | |
* `uvw` provides cross platform utilities for loading shared libraries and | |
* retrieving symbols from them, by means of the API offered by `libuv`. | |
*/ | |
-class SharedLib final: public UnderlyingType<SharedLib, uv_lib_t> { | |
+class UVW_EXTERN SharedLib final: public UnderlyingType<SharedLib, uv_lib_t> { | |
public: | |
explicit SharedLib(ConstructorAccess ca, std::shared_ptr<Loop> ref, std::string filename) noexcept; | |
@@ -67,4 +70,6 @@ class SharedLib final: public UnderlyingType<SharedLib, uv_lib_t> { | |
#include "lib.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_LIB_INCLUDE_H | |
diff --git a/src/uvw/loop.h b/src/uvw/loop.h | |
index 9832f0f..94c3a03 100644 | |
--- a/src/uvw/loop.h | |
+++ b/src/uvw/loop.h | |
@@ -14,6 +14,9 @@ | |
#include <uv.h> | |
#include "emitter.h" | |
#include "util.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -45,7 +48,7 @@ enum class UVRunMode: std::underlying_type_t<uv_run_mode> { | |
* users walk them as untyped instances.<br/> | |
* This can help to end all the pending requests by closing the handles. | |
*/ | |
-struct BaseHandle { | |
+struct UVW_EXTERN BaseHandle { | |
/** | |
* @brief Gets the category of the handle. | |
* | |
@@ -140,7 +143,7 @@ struct BaseHandle { | |
* It takes care of polling for I/O and scheduling callbacks to be run based on | |
* different sources of events. | |
*/ | |
-class Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop> { | |
+class UVW_EXTERN Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop> { | |
using Deleter = void(*)(uv_loop_t *); | |
template<typename, typename> | |
@@ -425,9 +428,9 @@ class Loop final: public Emitter<Loop>, public std::enable_shared_from_this<Loop | |
// (extern) explicit instantiations | |
-extern template bool Loop::run<Loop::Mode::DEFAULT>() noexcept; | |
-extern template bool Loop::run<Loop::Mode::ONCE>() noexcept; | |
-extern template bool Loop::run<Loop::Mode::NOWAIT>() noexcept; | |
+extern template UVW_EXTERN bool Loop::run<Loop::Mode::DEFAULT>() noexcept; | |
+extern template UVW_EXTERN bool Loop::run<Loop::Mode::ONCE>() noexcept; | |
+extern template UVW_EXTERN bool Loop::run<Loop::Mode::NOWAIT>() noexcept; | |
} | |
@@ -437,4 +440,6 @@ extern template bool Loop::run<Loop::Mode::NOWAIT>() noexcept; | |
#include "loop.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_LOOP_INCLUDE_H | |
diff --git a/src/uvw/pipe.h b/src/uvw/pipe.h | |
index d37ea40..c71c9dc 100644 | |
--- a/src/uvw/pipe.h | |
+++ b/src/uvw/pipe.h | |
@@ -10,6 +10,9 @@ | |
#include "stream.h" | |
#include "util.h" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -38,7 +41,7 @@ enum class UVChmodFlags: std::underlying_type_t<uv_poll_event> { | |
* * An optional boolean value that indicates if this pipe will be used for | |
* handle passing between processes. | |
*/ | |
-class PipeHandle final: public StreamHandle<PipeHandle, uv_pipe_t> { | |
+class UVW_EXTERN PipeHandle final: public StreamHandle<PipeHandle, uv_pipe_t> { | |
public: | |
using Chmod = details::UVChmodFlags; | |
@@ -164,4 +167,6 @@ class PipeHandle final: public StreamHandle<PipeHandle, uv_pipe_t> { | |
#include "pipe.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_PIPE_INCLUDE_H | |
diff --git a/src/uvw/poll.h b/src/uvw/poll.h | |
index 6030fd5..f12a25f 100644 | |
--- a/src/uvw/poll.h | |
+++ b/src/uvw/poll.h | |
@@ -7,6 +7,9 @@ | |
#include <uv.h> | |
#include "handle.hpp" | |
#include "util.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -31,7 +34,7 @@ enum class UVPollEvent: std::underlying_type_t<uv_poll_event> { | |
* | |
* It will be emitted by PollHandle according with its functionalities. | |
*/ | |
-struct PollEvent { | |
+struct UVW_EXTERN PollEvent { | |
explicit PollEvent(Flags<details::UVPollEvent> events) noexcept; | |
/** | |
@@ -46,6 +49,7 @@ struct PollEvent { | |
*/ | |
Flags<details::UVPollEvent> flags; | |
}; | |
+template class UVW_EXTERN Flags<details::UVPollEvent>; | |
/** | |
@@ -64,7 +68,7 @@ struct PollEvent { | |
* [documentation](http://docs.libuv.org/en/v1.x/poll.html) | |
* for further details. | |
*/ | |
-class PollHandle final: public Handle<PollHandle, uv_poll_t> { | |
+class UVW_EXTERN PollHandle final: public Handle<PollHandle, uv_poll_t> { | |
static void startCallback(uv_poll_t *handle, int status, int events); | |
public: | |
@@ -142,4 +146,6 @@ class PollHandle final: public Handle<PollHandle, uv_poll_t> { | |
#include "poll.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_POLL_INCLUDE_H | |
diff --git a/src/uvw/prepare.h b/src/uvw/prepare.h | |
index 736c7b8..9aab6e2 100644 | |
--- a/src/uvw/prepare.h | |
+++ b/src/uvw/prepare.h | |
@@ -5,6 +5,9 @@ | |
#include <uv.h> | |
#include "handle.hpp" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -15,7 +18,7 @@ namespace uvw { | |
* | |
* It will be emitted by PrepareHandle according with its functionalities. | |
*/ | |
-struct PrepareEvent {}; | |
+struct UVW_EXTERN PrepareEvent {}; | |
/** | |
@@ -26,7 +29,7 @@ struct PrepareEvent {}; | |
* | |
* To create a `PrepareHandle` through a `Loop`, no arguments are required. | |
*/ | |
-class PrepareHandle final: public Handle<PrepareHandle, uv_prepare_t> { | |
+class UVW_EXTERN PrepareHandle final: public Handle<PrepareHandle, uv_prepare_t> { | |
static void startCallback(uv_prepare_t *handle); | |
public: | |
@@ -62,4 +65,6 @@ class PrepareHandle final: public Handle<PrepareHandle, uv_prepare_t> { | |
#include "prepare.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_PREPARE_INCLUDE_H | |
diff --git a/src/uvw/process.h b/src/uvw/process.h | |
index f19fcc4..378a934 100644 | |
--- a/src/uvw/process.h | |
+++ b/src/uvw/process.h | |
@@ -11,6 +11,9 @@ | |
#include "stream.h" | |
#include "util.h" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -49,7 +52,7 @@ enum class UVStdIOFlags: std::underlying_type_t<uv_stdio_flags> { | |
* | |
* It will be emitted by ProcessHandle according with its functionalities. | |
*/ | |
-struct ExitEvent { | |
+struct UVW_EXTERN ExitEvent { | |
explicit ExitEvent(int64_t code, int sig) noexcept; | |
int64_t status; /*!< The exit status. */ | |
@@ -62,7 +65,7 @@ struct ExitEvent { | |
* Process handles will spawn a new process and allow the user to control it and | |
* establish communication channels with it using streams. | |
*/ | |
-class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> { | |
+class UVW_EXTERN ProcessHandle final: public Handle<ProcessHandle, uv_process_t> { | |
static void exitCallback(uv_process_t *handle, int64_t exitStatus, int termSignal); | |
public: | |
@@ -242,6 +245,7 @@ class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> { | |
Uid poUid; | |
Gid poGid; | |
}; | |
+template class UVW_EXTERN Flags<ProcessHandle::Process>; | |
} | |
@@ -251,4 +255,6 @@ class ProcessHandle final: public Handle<ProcessHandle, uv_process_t> { | |
#include "process.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_PROCESS_INCLUDE_H | |
diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp | |
index 212ad39..2dd773d 100644 | |
--- a/src/uvw/request.hpp | |
+++ b/src/uvw/request.hpp | |
@@ -7,6 +7,9 @@ | |
#include <memory> | |
#include <uv.h> | |
#include "resource.hpp" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -72,4 +75,6 @@ class Request: public Resource<T, U> { | |
} | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_REQUEST_INCLUDE_H | |
diff --git a/src/uvw/resource.hpp b/src/uvw/resource.hpp | |
index 53c8adb..4f6d4ed 100644 | |
--- a/src/uvw/resource.hpp | |
+++ b/src/uvw/resource.hpp | |
@@ -6,6 +6,9 @@ | |
#include <utility> | |
#include "emitter.h" | |
#include "underlying_type.hpp" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -70,4 +73,6 @@ class Resource: public UnderlyingType<T, U>, public Emitter<T>, public std::enab | |
} | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_RESOURCE_INCLUDE_H | |
diff --git a/src/uvw/signal.h b/src/uvw/signal.h | |
index 93b6905..d357d14 100644 | |
--- a/src/uvw/signal.h | |
+++ b/src/uvw/signal.h | |
@@ -5,6 +5,9 @@ | |
#include <uv.h> | |
#include "handle.hpp" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -15,7 +18,7 @@ namespace uvw { | |
* | |
* It will be emitted by SignalHandle according with its functionalities. | |
*/ | |
-struct SignalEvent { | |
+struct UVW_EXTERN SignalEvent { | |
explicit SignalEvent(int sig) noexcept; | |
int signum; /*!< The signal being monitored by this handle. */ | |
@@ -35,7 +38,7 @@ struct SignalEvent { | |
* [documentation](http://docs.libuv.org/en/v1.x/signal.html) | |
* for further details. | |
*/ | |
-class SignalHandle final: public Handle<SignalHandle, uv_signal_t> { | |
+class UVW_EXTERN SignalHandle final: public Handle<SignalHandle, uv_signal_t> { | |
static void startCallback(uv_signal_t *handle, int signum); | |
public: | |
@@ -86,4 +89,6 @@ class SignalHandle final: public Handle<SignalHandle, uv_signal_t> { | |
#include "signal.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_SIGNAL_INCLUDE_H | |
diff --git a/src/uvw/stream.cpp b/src/uvw/stream.cpp | |
index 4d558e0..323f8d6 100644 | |
--- a/src/uvw/stream.cpp | |
+++ b/src/uvw/stream.cpp | |
@@ -7,6 +7,16 @@ | |
namespace uvw { | |
+ template<typename Deleter> | |
+ UVW_INLINE void WriteReq<Deleter>::write(uv_stream_t *handle) { | |
+ this->invoke(&uv_write, this->get(), handle, &buf, 1, &this->template defaultCallback<WriteEvent>); | |
+ } | |
+ | |
+ template<typename Deleter> | |
+ UVW_INLINE void WriteReq<Deleter>::write(uv_stream_t *handle, uv_stream_t *send) { | |
+ this->invoke(&uv_write2, this->get(), handle, &buf, 1, send, &this->template defaultCallback<WriteEvent>); | |
+ } | |
+ | |
UVW_INLINE DataEvent::DataEvent(std::unique_ptr<char[]> buf, std::size_t len) noexcept | |
: data{std::move(buf)}, length{len} | |
@@ -17,5 +27,8 @@ UVW_INLINE void details::ShutdownReq::shutdown(uv_stream_t *handle) { | |
invoke(&uv_shutdown, get(), handle, &defaultCallback<ShutdownEvent>); | |
} | |
+template void WriteReq<std::default_delete<char []> >::write(uv_stream_s*); | |
+template void WriteReq<void (*)(char*)>::write(uv_stream_s*); | |
+template void WriteReq<std::default_delete<char []> >::write(uv_stream_t *handle, uv_stream_t *send); | |
} | |
diff --git a/src/uvw/stream.h b/src/uvw/stream.h | |
index 88d6dc1..66b1d6d 100644 | |
--- a/src/uvw/stream.h | |
+++ b/src/uvw/stream.h | |
@@ -11,6 +11,9 @@ | |
#include "request.hpp" | |
#include "handle.hpp" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -21,7 +24,7 @@ namespace uvw { | |
* | |
* It will be emitted by StreamHandle according with its functionalities. | |
*/ | |
-struct ConnectEvent {}; | |
+struct UVW_EXTERN ConnectEvent {}; | |
/** | |
@@ -29,7 +32,7 @@ struct ConnectEvent {}; | |
* | |
* It will be emitted by StreamHandle according with its functionalities. | |
*/ | |
-struct EndEvent {}; | |
+struct UVW_EXTERN EndEvent {}; | |
/** | |
@@ -37,7 +40,7 @@ struct EndEvent {}; | |
* | |
* It will be emitted by StreamHandle according with its functionalities. | |
*/ | |
-struct ListenEvent {}; | |
+struct UVW_EXTERN ListenEvent {}; | |
/** | |
@@ -45,7 +48,7 @@ struct ListenEvent {}; | |
* | |
* It will be emitted by StreamHandle according with its functionalities. | |
*/ | |
-struct ShutdownEvent {}; | |
+struct UVW_EXTERN ShutdownEvent {}; | |
/** | |
@@ -53,7 +56,7 @@ struct ShutdownEvent {}; | |
* | |
* It will be emitted by StreamHandle according with its functionalities. | |
*/ | |
-struct WriteEvent {}; | |
+struct UVW_EXTERN WriteEvent {}; | |
/** | |
@@ -61,7 +64,7 @@ struct WriteEvent {}; | |
* | |
* It will be emitted by StreamHandle according with its functionalities. | |
*/ | |
-struct DataEvent { | |
+struct UVW_EXTERN DataEvent { | |
explicit DataEvent(std::unique_ptr<char[]> buf, std::size_t len) noexcept; | |
std::unique_ptr<char[]> data; /*!< A bunch of data read on the stream. */ | |
@@ -72,7 +75,7 @@ struct DataEvent { | |
namespace details { | |
-struct ConnectReq final: public Request<ConnectReq, uv_connect_t> { | |
+struct UVW_EXTERN ConnectReq final: public Request<ConnectReq, uv_connect_t> { | |
using Request::Request; | |
template<typename F, typename... Args> | |
@@ -82,40 +85,37 @@ struct ConnectReq final: public Request<ConnectReq, uv_connect_t> { | |
}; | |
-struct ShutdownReq final: public Request<ShutdownReq, uv_shutdown_t> { | |
+struct UVW_EXTERN ShutdownReq final: public Request<ShutdownReq, uv_shutdown_t> { | |
using Request::Request; | |
void shutdown(uv_stream_t *handle); | |
}; | |
-template<typename Deleter> | |
-class WriteReq final: public Request<WriteReq<Deleter>, uv_write_t> { | |
- using ConstructorAccess = typename Request<WriteReq<Deleter>, uv_write_t>::ConstructorAccess; | |
-public: | |
- WriteReq(ConstructorAccess ca, std::shared_ptr<Loop> loop, std::unique_ptr<char[], Deleter> dt, unsigned int len) | |
- : Request<WriteReq<Deleter>, uv_write_t>{ca, std::move(loop)}, | |
- data{std::move(dt)}, | |
- buf{uv_buf_init(data.get(), len)} | |
- {} | |
- void write(uv_stream_t *handle) { | |
- this->invoke(&uv_write, this->get(), handle, &buf, 1, &this->template defaultCallback<WriteEvent>); | |
- } | |
+} | |
- void write(uv_stream_t *handle, uv_stream_t *send) { | |
- this->invoke(&uv_write2, this->get(), handle, &buf, 1, send, &this->template defaultCallback<WriteEvent>); | |
- } | |
+ template<typename Deleter> | |
+ class UVW_EXTERN WriteReq final: public Request<WriteReq<Deleter>, uv_write_t> { | |
+ using ConstructorAccess = typename Request<WriteReq<Deleter>, uv_write_t>::ConstructorAccess; | |
-private: | |
- std::unique_ptr<char[], Deleter> data; | |
- uv_buf_t buf; | |
-}; | |
+ public: | |
+ WriteReq(WriteReq::ConstructorAccess ca, std::shared_ptr<Loop> loop, | |
+ std::unique_ptr<char[], Deleter> dt, unsigned int len) | |
+ : Request<WriteReq<Deleter>, uv_write_t>{ca, std::move(loop)}, | |
+ data{std::move(dt)}, | |
+ buf{uv_buf_init(data.get(), len)} | |
+ {} | |
+ void write(uv_stream_t *handle); | |
-} | |
+ void write(uv_stream_t *handle, uv_stream_t *send); | |
+ private: | |
+ std::unique_ptr<char[], Deleter> data; | |
+ uv_buf_t buf; | |
+ }; | |
/** | |
* @brief The StreamHandle handle. | |
@@ -254,7 +254,7 @@ class StreamHandle: public Handle<T, U> { | |
*/ | |
template<typename Deleter> | |
void write(std::unique_ptr<char[], Deleter> data, unsigned int len) { | |
- auto req = this->loop().template resource<details::WriteReq<Deleter>>(std::move(data), len); | |
+ auto req = this->loop().template resource<WriteReq<Deleter>>(std::move(data), len); | |
auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { | |
ptr->publish(event); | |
}; | |
@@ -277,7 +277,7 @@ class StreamHandle: public Handle<T, U> { | |
* @param len The lenght of the submitted data. | |
*/ | |
void write(char *data, unsigned int len) { | |
- auto req = this->loop().template resource<details::WriteReq<void(*)(char *)>>(std::unique_ptr<char[], void(*)(char *)>{data, [](char *) {}}, len); | |
+ auto req = this->loop().template resource<WriteReq<void(*)(char *)>>(std::unique_ptr<char[], void(*)(char *)>{data, [](char *) {}}, len); | |
auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { | |
ptr->publish(event); | |
}; | |
@@ -308,7 +308,7 @@ class StreamHandle: public Handle<T, U> { | |
*/ | |
template<typename S, typename Deleter> | |
void write(S &send, std::unique_ptr<char[], Deleter> data, unsigned int len) { | |
- auto req = this->loop().template resource<details::WriteReq<Deleter>>(std::move(data), len); | |
+ auto req = this->loop().template resource<WriteReq<Deleter>>(std::move(data), len); | |
auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { | |
ptr->publish(event); | |
}; | |
@@ -339,7 +339,7 @@ class StreamHandle: public Handle<T, U> { | |
*/ | |
template<typename S> | |
void write(S &send, char *data, unsigned int len) { | |
- auto req = this->loop().template resource<details::WriteReq<void(*)(char *)>>(std::unique_ptr<char[], void(*)(char *)>{data, [](char *) {}}, len); | |
+ auto req = this->loop().template resource<WriteReq<void(*)(char *)>>(std::unique_ptr<char[], void(*)(char *)>{data, [](char *) {}}, len); | |
auto listener = [ptr = this->shared_from_this()](const auto &event, const auto &) { | |
ptr->publish(event); | |
}; | |
@@ -439,6 +439,10 @@ class StreamHandle: public Handle<T, U> { | |
} | |
}; | |
+extern template UVW_EXTERN void WriteReq<std::default_delete<char []> >::write(uv_stream_s*); | |
+extern template UVW_EXTERN void WriteReq<void (*)(char*)>::write(uv_stream_s*); | |
+extern template UVW_EXTERN void WriteReq<std::default_delete<char []> >::write(uv_stream_t *handle, uv_stream_t *send); | |
+ | |
} | |
@@ -447,4 +451,6 @@ class StreamHandle: public Handle<T, U> { | |
#include "stream.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_STREAM_INCLUDE_H | |
diff --git a/src/uvw/tcp.h b/src/uvw/tcp.h | |
index 2b1e255..30b4a90 100644 | |
--- a/src/uvw/tcp.h | |
+++ b/src/uvw/tcp.h | |
@@ -11,6 +11,9 @@ | |
#include "request.hpp" | |
#include "stream.h" | |
#include "util.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -43,7 +46,7 @@ enum class UVTCPFlags: std::underlying_type_t<uv_tcp_flags> { | |
* [documentation](http://docs.libuv.org/en/v1.x/tcp.html#c.uv_tcp_init_ex) | |
* for further details. | |
*/ | |
-class TCPHandle final: public StreamHandle<TCPHandle, uv_tcp_t> { | |
+class UVW_EXTERN TCPHandle final: public StreamHandle<TCPHandle, uv_tcp_t> { | |
public: | |
using Time = std::chrono::duration<unsigned int>; | |
using Bind = details::UVTCPFlags; | |
@@ -232,23 +235,23 @@ class TCPHandle final: public StreamHandle<TCPHandle, uv_tcp_t> { | |
// (extern) explicit instantiations | |
-extern template void TCPHandle::bind<IPv4>(std::string, unsigned int, Flags<Bind>); | |
-extern template void TCPHandle::bind<IPv6>(std::string, unsigned int, Flags<Bind>); | |
+extern template UVW_EXTERN void TCPHandle::bind<IPv4>(std::string, unsigned int, Flags<Bind>); | |
+extern template UVW_EXTERN void TCPHandle::bind<IPv6>(std::string, unsigned int, Flags<Bind>); | |
-extern template void TCPHandle::bind<IPv4>(Addr, Flags<Bind>); | |
-extern template void TCPHandle::bind<IPv6>(Addr, Flags<Bind>); | |
+extern template UVW_EXTERN void TCPHandle::bind<IPv4>(Addr, Flags<Bind>); | |
+extern template UVW_EXTERN void TCPHandle::bind<IPv6>(Addr, Flags<Bind>); | |
-extern template Addr TCPHandle::sock<IPv4>() const noexcept; | |
-extern template Addr TCPHandle::sock<IPv6>() const noexcept; | |
+extern template UVW_EXTERN Addr TCPHandle::sock<IPv4>() const noexcept; | |
+extern template UVW_EXTERN Addr TCPHandle::sock<IPv6>() const noexcept; | |
-extern template Addr TCPHandle::peer<IPv4>() const noexcept; | |
-extern template Addr TCPHandle::peer<IPv6>() const noexcept; | |
+extern template UVW_EXTERN Addr TCPHandle::peer<IPv4>() const noexcept; | |
+extern template UVW_EXTERN Addr TCPHandle::peer<IPv6>() const noexcept; | |
-extern template void TCPHandle::connect<IPv4>(std::string, unsigned int); | |
-extern template void TCPHandle::connect<IPv6>(std::string, unsigned int); | |
+extern template UVW_EXTERN void TCPHandle::connect<IPv4>(std::string, unsigned int); | |
+extern template UVW_EXTERN void TCPHandle::connect<IPv6>(std::string, unsigned int); | |
-extern template void TCPHandle::connect<IPv4>(Addr addr); | |
-extern template void TCPHandle::connect<IPv6>(Addr addr); | |
+extern template UVW_EXTERN void TCPHandle::connect<IPv4>(Addr addr); | |
+extern template UVW_EXTERN void TCPHandle::connect<IPv6>(Addr addr); | |
} | |
@@ -258,4 +261,6 @@ extern template void TCPHandle::connect<IPv6>(Addr addr); | |
#include "tcp.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_TCP_INCLUDE_H | |
diff --git a/src/uvw/thread.h b/src/uvw/thread.h | |
index 912d8a1..07481d3 100644 | |
--- a/src/uvw/thread.h | |
+++ b/src/uvw/thread.h | |
@@ -10,6 +10,9 @@ | |
#include <uv.h> | |
#include "loop.h" | |
#include "underlying_type.hpp" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -46,7 +49,7 @@ class Barrier; | |
* that it can be assigned to an `std::function<void(std::shared_ptr<void>)>`. | |
* * An optional payload the type of which is `std::shared_ptr<void>`. | |
*/ | |
-class Thread final: public UnderlyingType<Thread, uv_thread_t> { | |
+class UVW_EXTERN Thread final: public UnderlyingType<Thread, uv_thread_t> { | |
using InternalTask = std::function<void(std::shared_ptr<void>)>; | |
static void createCallback(void *arg); | |
@@ -114,7 +117,7 @@ class Thread final: public UnderlyingType<Thread, uv_thread_t> { | |
* seen as a global variable that is only visible to a particular thread and not | |
* the whole program. | |
*/ | |
-class ThreadLocalStorage final: public UnderlyingType<ThreadLocalStorage, uv_key_t> { | |
+class UVW_EXTERN ThreadLocalStorage final: public UnderlyingType<ThreadLocalStorage, uv_key_t> { | |
public: | |
explicit ThreadLocalStorage(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept; | |
@@ -148,7 +151,7 @@ class ThreadLocalStorage final: public UnderlyingType<ThreadLocalStorage, uv_key | |
* Runs a function once and only once. Concurrent calls to `once` will block all | |
* callers except one (it’s unspecified which one). | |
*/ | |
-class Once final: public UnderlyingType<Once, uv_once_t> { | |
+class UVW_EXTERN Once final: public UnderlyingType<Once, uv_once_t> { | |
static uv_once_t* guard() noexcept; | |
public: | |
@@ -181,7 +184,7 @@ class Once final: public UnderlyingType<Once, uv_once_t> { | |
* * An option boolean that specifies if the mutex is a recursive one. The | |
* default value is false, the mutex isn't recursive. | |
*/ | |
-class Mutex final: public UnderlyingType<Mutex, uv_mutex_t> { | |
+class UVW_EXTERN Mutex final: public UnderlyingType<Mutex, uv_mutex_t> { | |
friend class Condition; | |
public: | |
@@ -210,7 +213,7 @@ class Mutex final: public UnderlyingType<Mutex, uv_mutex_t> { | |
/** | |
* @brief The RWLock wrapper. | |
*/ | |
-class RWLock final: public UnderlyingType<RWLock, uv_rwlock_t> { | |
+class UVW_EXTERN RWLock final: public UnderlyingType<RWLock, uv_rwlock_t> { | |
public: | |
explicit RWLock(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept; | |
@@ -257,7 +260,7 @@ class RWLock final: public UnderlyingType<RWLock, uv_rwlock_t> { | |
* | |
* * An unsigned integer that specifies the initial value for the semaphore. | |
*/ | |
-class Semaphore final: public UnderlyingType<Semaphore, uv_sem_t> { | |
+class UVW_EXTERN Semaphore final: public UnderlyingType<Semaphore, uv_sem_t> { | |
public: | |
explicit Semaphore(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int value) noexcept; | |
@@ -284,7 +287,7 @@ class Semaphore final: public UnderlyingType<Semaphore, uv_sem_t> { | |
/** | |
* @brief The Condition wrapper. | |
*/ | |
-class Condition final: public UnderlyingType<Condition, uv_cond_t> { | |
+class UVW_EXTERN Condition final: public UnderlyingType<Condition, uv_cond_t> { | |
public: | |
explicit Condition(ConstructorAccess ca, std::shared_ptr<Loop> ref) noexcept; | |
@@ -344,7 +347,7 @@ class Condition final: public UnderlyingType<Condition, uv_cond_t> { | |
* `wait` before any of them successfully return from the call. The value | |
* specified must be greater than zero. | |
*/ | |
-class Barrier final: public UnderlyingType<Barrier, uv_barrier_t> { | |
+class UVW_EXTERN Barrier final: public UnderlyingType<Barrier, uv_barrier_t> { | |
public: | |
explicit Barrier(ConstructorAccess ca, std::shared_ptr<Loop> ref, unsigned int count) noexcept; | |
@@ -365,4 +368,6 @@ class Barrier final: public UnderlyingType<Barrier, uv_barrier_t> { | |
#include "thread.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_THREAD_INCLUDE_H | |
diff --git a/src/uvw/timer.h b/src/uvw/timer.h | |
index b1fbb43..443de0e 100644 | |
--- a/src/uvw/timer.h | |
+++ b/src/uvw/timer.h | |
@@ -6,6 +6,9 @@ | |
#include <uv.h> | |
#include "handle.hpp" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -16,7 +19,7 @@ namespace uvw { | |
* | |
* It will be emitted by TimerHandle according with its functionalities. | |
*/ | |
-struct TimerEvent {}; | |
+struct UVW_EXTERN TimerEvent {}; | |
/** | |
@@ -26,7 +29,7 @@ struct TimerEvent {}; | |
* | |
* To create a `TimerHandle` through a `Loop`, no arguments are required. | |
*/ | |
-class TimerHandle final: public Handle<TimerHandle, uv_timer_t> { | |
+class UVW_EXTERN TimerHandle final: public Handle<TimerHandle, uv_timer_t> { | |
static void startCallback(uv_timer_t *handle); | |
public: | |
@@ -104,4 +107,6 @@ class TimerHandle final: public Handle<TimerHandle, uv_timer_t> { | |
#include "timer.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_TIMER_INCLUDE_H | |
diff --git a/src/uvw/tty.h b/src/uvw/tty.h | |
index bbfb1ff..9b283cd 100644 | |
--- a/src/uvw/tty.h | |
+++ b/src/uvw/tty.h | |
@@ -7,6 +7,9 @@ | |
#include <uv.h> | |
#include "stream.h" | |
#include "util.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -15,7 +18,7 @@ namespace uvw { | |
namespace details { | |
-struct ResetModeMemo { | |
+struct UVW_EXTERN ResetModeMemo { | |
~ResetModeMemo(); | |
}; | |
@@ -54,7 +57,7 @@ enum class UVTTYVTermStateT: std::underlying_type_t<uv_tty_vtermstate_t> { | |
* [documentation](http://docs.libuv.org/en/v1.x/tty.html#c.uv_tty_init) | |
* for further details. | |
*/ | |
-class TTYHandle final: public StreamHandle<TTYHandle, uv_tty_t> { | |
+class UVW_EXTERN TTYHandle final: public StreamHandle<TTYHandle, uv_tty_t> { | |
static std::shared_ptr<details::ResetModeMemo> resetModeMemo(); | |
public: | |
@@ -152,4 +155,6 @@ class TTYHandle final: public StreamHandle<TTYHandle, uv_tty_t> { | |
#include "tty.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_TTY_INCLUDE_H | |
diff --git a/src/uvw/type_factory/type_factory.cpp b/src/uvw/type_factory/type_factory.cpp | |
new file mode 100644 | |
index 0000000..f0df4f9 | |
--- /dev/null | |
+++ b/src/uvw/type_factory/type_factory.cpp | |
@@ -0,0 +1,264 @@ | |
+#include "type_factory.h" | |
+ | |
+#include <uvw.hpp> | |
+ | |
+namespace uvw::details { | |
+ template<typename T> | |
+ std::size_t type_factory<T>::next_type() noexcept { | |
+ static std::size_t counter = 0; | |
+ return counter++; | |
+ } | |
+ | |
+ template<typename T> | |
+ template<typename> | |
+ std::size_t type_factory<T>::event_type() noexcept { | |
+ static std::size_t value = next_type(); | |
+ return value; | |
+ } | |
+} | |
+ | |
+ | |
+namespace uvw { | |
+ template std::size_t details::type_factory<IdleHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<IdleHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<IdleHandle>::event_type<IdleEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<AsyncHandle>::event_type<AsyncEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<AsyncHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<WorkReq>::event_type<WorkEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 1> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 2> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 3> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 4> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 5> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 6> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 7> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 8> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 9> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 10> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 11> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 12> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 13> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 14> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 15> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 16> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 17> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 18> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 19> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 20> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 21> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 22> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 23> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 24> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 25> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 26> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 27> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 28> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 29> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 30> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 31> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 32> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 33> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 34> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 35> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 36> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 37> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 38> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<FsEvent<(details::UVFsType) 39> >() noexcept; | |
+ | |
+ | |
+ template std::size_t details::type_factory<details::ShutdownReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 11> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<GetNameInfoReq>::event_type<NameInfoEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TimerHandle>::event_type<TimerEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<CheckHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 27> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<details::SendReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 9> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TCPHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<ProcessHandle>::event_type<ExitEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PrepareHandle>::event_type<PrepareEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TCPHandle>::event_type<ConnectEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsEventHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 15> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsEventHandle>::event_type<FsEventEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TimerHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TCPHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<GetNameInfoReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PrepareHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<WorkReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PollHandle>::event_type<PollEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PollHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<SignalHandle>::event_type<SignalEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PipeHandle>::event_type<ConnectEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<details::ShutdownReq>::event_type<ShutdownEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 5> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TTYHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<UDPHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<Loop>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<UDPHandle>::event_type<SendEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PipeHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsPollHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<GetAddrInfoReq>::event_type<AddrInfoEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<details::ConnectReq>::event_type<ConnectEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<UDPHandle>::event_type<UDPDataEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<details::ConnectReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 14> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsPollHandle>::event_type<FsPollEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 16> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<GetAddrInfoReq>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<UDPHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 1> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<details::SendReq>::event_type<SendEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<SignalHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 2> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 3> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 8> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FileReq>::event_type<FsEvent<(details::UVFsType) 4> >() noexcept; | |
+ | |
+ template std::size_t details::type_factory<ProcessHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<ProcessHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TTYHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PollHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PipeHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<CheckHandle>::event_type<CheckEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<CheckHandle>::event_type<CloseEvent>() noexcept; | |
+ template std::size_t details::type_factory<TimerHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<AsyncHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<PrepareHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FsEventHandle>::event_type<CloseEvent>() noexcept; | |
+ template std::size_t details::type_factory<FsPollHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TCPHandle>::event_type<WriteEvent>() noexcept; | |
+ template std::size_t details::type_factory<TCPHandle>::event_type<EndEvent>() noexcept; | |
+ template std::size_t details::type_factory<TCPHandle>::event_type<DataEvent>() noexcept; | |
+ template std::size_t details::type_factory<TCPHandle>::event_type<ListenEvent>() noexcept; | |
+ template std::size_t details::type_factory<TCPHandle>::event_type<ShutdownEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TTYHandle>::event_type<WriteEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<uvw::PipeHandle>::event_type<WriteEvent>() noexcept; | |
+ template std::size_t details::type_factory<uvw::PipeHandle>::event_type<EndEvent>() noexcept; | |
+ template std::size_t details::type_factory<uvw::PipeHandle>::event_type<DataEvent>() noexcept; | |
+ template std::size_t details::type_factory<uvw::PipeHandle>::event_type<ListenEvent>() noexcept; | |
+ template std::size_t details::type_factory<uvw::PipeHandle>::event_type<ShutdownEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<SignalHandle>::event_type<CheckEvent>() noexcept; | |
+ template std::size_t details::type_factory<SignalHandle>::event_type<CloseEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<WriteReq<std::default_delete<char []> > >::event_type<ErrorEvent>() noexcept; | |
+ template std::size_t details::type_factory<WriteReq<std::default_delete<char []> > >::event_type<WriteEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<WriteReq<void (*)(char*) > >::event_type<ErrorEvent>() noexcept; | |
+ template std::size_t details::type_factory<WriteReq<void (*)(char*) > >::event_type<WriteEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<FakeHandle>::event_type<CloseEvent>() noexcept; | |
+ template std::size_t details::type_factory<FakeHandle>::event_type<ErrorEvent>() noexcept; | |
+ | |
+ template std::size_t details::type_factory<TestEmitter>::event_type<FakeEvent>() noexcept; | |
+ template std::size_t details::type_factory<TestEmitter>::event_type<ErrorEvent>() noexcept; | |
+ | |
+} | |
diff --git a/src/uvw/type_factory/type_factory.h b/src/uvw/type_factory/type_factory.h | |
new file mode 100644 | |
index 0000000..32b20a0 | |
--- /dev/null | |
+++ b/src/uvw/type_factory/type_factory.h | |
@@ -0,0 +1,18 @@ | |
+#ifndef UVW_TYPE_FACTORY_H | |
+#define UVW_TYPE_FACTORY_H | |
+ | |
+#include <uvw/config.h> | |
+#include <cstddef> | |
+ | |
+namespace uvw::details { | |
+ template<typename T> | |
+ struct UVW_EXTERN type_factory { | |
+ template<typename> | |
+ static std::size_t event_type() noexcept; | |
+ | |
+ static std::size_t next_type() noexcept; | |
+ }; | |
+} | |
+ | |
+ | |
+#endif //UVW_TYPE_FACTORY_H | |
diff --git a/src/uvw/udp.h b/src/uvw/udp.h | |
index 68769a8..3251b02 100644 | |
--- a/src/uvw/udp.h | |
+++ b/src/uvw/udp.h | |
@@ -11,6 +11,9 @@ | |
#include "request.hpp" | |
#include "handle.hpp" | |
#include "util.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -21,7 +24,7 @@ namespace uvw { | |
* | |
* It will be emitted by UDPHandle according with its functionalities. | |
*/ | |
-struct SendEvent {}; | |
+struct UVW_EXTERN SendEvent {}; | |
/** | |
@@ -29,7 +32,7 @@ struct SendEvent {}; | |
* | |
* It will be emitted by UDPHandle according with its functionalities. | |
*/ | |
-struct UDPDataEvent { | |
+struct UVW_EXTERN UDPDataEvent { | |
explicit UDPDataEvent(Addr sndr, std::unique_ptr<const char[]> buf, std::size_t len, bool part) noexcept; | |
std::unique_ptr<const char[]> data; /*!< A bunch of data read on the stream. */ | |
@@ -57,7 +60,7 @@ enum class UVMembership: std::underlying_type_t<uv_membership> { | |
}; | |
-class SendReq final: public Request<SendReq, uv_udp_send_t> { | |
+class UVW_EXTERN SendReq final: public Request<SendReq, uv_udp_send_t> { | |
public: | |
using Deleter = void(*)(char *); | |
@@ -90,7 +93,7 @@ class SendReq final: public Request<SendReq, uv_udp_send_t> { | |
* [documentation](http://docs.libuv.org/en/v1.x/udp.html#c.uv_udp_init_ex) | |
* for further details. | |
*/ | |
-class UDPHandle final: public Handle<UDPHandle, uv_udp_t> { | |
+class UVW_EXTERN UDPHandle final: public Handle<UDPHandle, uv_udp_t> { | |
template<typename I> | |
static void recvCallback(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const sockaddr *addr, unsigned flags) { | |
const typename details::IpTraits<I>::Type *aptr = reinterpret_cast<const typename details::IpTraits<I>::Type *>(addr); | |
@@ -578,62 +581,62 @@ class UDPHandle final: public Handle<UDPHandle, uv_udp_t> { | |
// (extern) explicit instantiations | |
-extern template void UDPHandle::connect<IPv4>(std::string, unsigned int); | |
-extern template void UDPHandle::connect<IPv6>(std::string, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::connect<IPv4>(std::string, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::connect<IPv6>(std::string, unsigned int); | |
-extern template void UDPHandle::connect<IPv4>(Addr); | |
-extern template void UDPHandle::connect<IPv6>(Addr); | |
+extern template UVW_EXTERN void UDPHandle::connect<IPv4>(Addr); | |
+extern template UVW_EXTERN void UDPHandle::connect<IPv6>(Addr); | |
-extern template Addr UDPHandle::peer<IPv4>() const noexcept; | |
-extern template Addr UDPHandle::peer<IPv6>() const noexcept; | |
+extern template UVW_EXTERN Addr UDPHandle::peer<IPv4>() const noexcept; | |
+extern template UVW_EXTERN Addr UDPHandle::peer<IPv6>() const noexcept; | |
-extern template void UDPHandle::bind<IPv4>(std::string, unsigned int, Flags<Bind>); | |
-extern template void UDPHandle::bind<IPv6>(std::string, unsigned int, Flags<Bind>); | |
+extern template UVW_EXTERN void UDPHandle::bind<IPv4>(std::string, unsigned int, Flags<Bind>); | |
+extern template UVW_EXTERN void UDPHandle::bind<IPv6>(std::string, unsigned int, Flags<Bind>); | |
-extern template void UDPHandle::bind<IPv4>(Addr, Flags<Bind>); | |
-extern template void UDPHandle::bind<IPv6>(Addr, Flags<Bind>); | |
+extern template UVW_EXTERN void UDPHandle::bind<IPv4>(Addr, Flags<Bind>); | |
+extern template UVW_EXTERN void UDPHandle::bind<IPv6>(Addr, Flags<Bind>); | |
-extern template Addr UDPHandle::sock<IPv4>() const noexcept; | |
-extern template Addr UDPHandle::sock<IPv6>() const noexcept; | |
+extern template UVW_EXTERN Addr UDPHandle::sock<IPv4>() const noexcept; | |
+extern template UVW_EXTERN Addr UDPHandle::sock<IPv6>() const noexcept; | |
-extern template bool UDPHandle::multicastMembership<IPv4>(std::string, std::string, Membership); | |
-extern template bool UDPHandle::multicastMembership<IPv6>(std::string, std::string, Membership); | |
+extern template UVW_EXTERN bool UDPHandle::multicastMembership<IPv4>(std::string, std::string, Membership); | |
+extern template UVW_EXTERN bool UDPHandle::multicastMembership<IPv6>(std::string, std::string, Membership); | |
-extern template bool UDPHandle::multicastInterface<IPv4>(std::string); | |
-extern template bool UDPHandle::multicastInterface<IPv6>(std::string); | |
+extern template UVW_EXTERN bool UDPHandle::multicastInterface<IPv4>(std::string); | |
+extern template UVW_EXTERN bool UDPHandle::multicastInterface<IPv6>(std::string); | |
-extern template void UDPHandle::send<IPv4>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
-extern template void UDPHandle::send<IPv6>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::send<IPv4>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::send<IPv6>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
-extern template void UDPHandle::send<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int); | |
-extern template void UDPHandle::send<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::send<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::send<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int); | |
-extern template void UDPHandle::send<IPv4>(std::string, unsigned int, char *, unsigned int); | |
-extern template void UDPHandle::send<IPv6>(std::string, unsigned int, char *, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::send<IPv4>(std::string, unsigned int, char *, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::send<IPv6>(std::string, unsigned int, char *, unsigned int); | |
-extern template void UDPHandle::send<IPv4>(Addr, char *, unsigned int); | |
-extern template void UDPHandle::send<IPv6>(Addr, char *, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::send<IPv4>(Addr, char *, unsigned int); | |
+extern template UVW_EXTERN void UDPHandle::send<IPv6>(Addr, char *, unsigned int); | |
-extern template int UDPHandle::trySend<IPv4>(const sockaddr &, std::unique_ptr<char[]>, unsigned int); | |
-extern template int UDPHandle::trySend<IPv6>(const sockaddr &, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(const sockaddr &, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(const sockaddr &, std::unique_ptr<char[]>, unsigned int); | |
-extern template int UDPHandle::trySend<IPv4>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
-extern template int UDPHandle::trySend<IPv6>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(std::string, unsigned int, std::unique_ptr<char[]>, unsigned int); | |
-extern template int UDPHandle::trySend<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int); | |
-extern template int UDPHandle::trySend<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(Addr, std::unique_ptr<char[]>, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(Addr, std::unique_ptr<char[]>, unsigned int); | |
-extern template int UDPHandle::trySend<IPv4>(const sockaddr &, char *, unsigned int); | |
-extern template int UDPHandle::trySend<IPv6>(const sockaddr &, char *, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(const sockaddr &, char *, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(const sockaddr &, char *, unsigned int); | |
-extern template int UDPHandle::trySend<IPv4>(std::string, unsigned int, char *, unsigned int); | |
-extern template int UDPHandle::trySend<IPv6>(std::string, unsigned int, char *, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(std::string, unsigned int, char *, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(std::string, unsigned int, char *, unsigned int); | |
-extern template int UDPHandle::trySend<IPv4>(Addr, char *, unsigned int); | |
-extern template int UDPHandle::trySend<IPv6>(Addr, char *, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv4>(Addr, char *, unsigned int); | |
+extern template UVW_EXTERN int UDPHandle::trySend<IPv6>(Addr, char *, unsigned int); | |
-extern template void UDPHandle::recv<IPv4>(); | |
-extern template void UDPHandle::recv<IPv6>(); | |
+extern template UVW_EXTERN void UDPHandle::recv<IPv4>(); | |
+extern template UVW_EXTERN void UDPHandle::recv<IPv6>(); | |
} | |
@@ -642,4 +645,6 @@ extern template void UDPHandle::recv<IPv6>(); | |
#include "udp.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_UDP_INCLUDE_H | |
diff --git a/src/uvw/underlying_type.hpp b/src/uvw/underlying_type.hpp | |
index 06c4a57..78cd5d7 100644 | |
--- a/src/uvw/underlying_type.hpp | |
+++ b/src/uvw/underlying_type.hpp | |
@@ -6,6 +6,9 @@ | |
#include <type_traits> | |
#include <utility> | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -116,4 +119,6 @@ class UnderlyingType { | |
} | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_UNDERLYING_TYPE_INCLUDE_H | |
diff --git a/src/uvw/util.cpp b/src/uvw/util.cpp | |
index 95ef325..2f8a3a2 100644 | |
--- a/src/uvw/util.cpp | |
+++ b/src/uvw/util.cpp | |
@@ -69,6 +69,10 @@ UVW_INLINE std::string UtsName::machine() const noexcept { | |
return utsname ? utsname->machine : ""; | |
} | |
+const details::IpTraits<IPv4>::AddrFuncType details::IpTraits<IPv4>::addrFunc = &uv_ip4_addr; | |
+const details::IpTraits<IPv4>::NameFuncType details::IpTraits<IPv4>::nameFunc = &uv_ip4_name; | |
+const details::IpTraits<IPv6>::AddrFuncType details::IpTraits<IPv6>::addrFunc = &uv_ip6_addr; | |
+const details::IpTraits<IPv6>::NameFuncType details::IpTraits<IPv6>::nameFunc = &uv_ip6_name; | |
UVW_INLINE PidType Utilities::OS::pid() noexcept { | |
return uv_os_getpid(); | |
diff --git a/src/uvw/util.h b/src/uvw/util.h | |
index 4227137..93c7b34 100644 | |
--- a/src/uvw/util.h | |
+++ b/src/uvw/util.h | |
@@ -11,6 +11,9 @@ | |
#include <memory> | |
#include <array> | |
#include <uv.h> | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -177,7 +180,7 @@ class Flags final { | |
/** | |
* @brief Windows size representation. | |
*/ | |
-struct WinSize { | |
+struct UVW_EXTERN WinSize { | |
int width; /*!< The _width_ of the given window. */ | |
int height; /*!< The _height_ of the given window. */ | |
}; | |
@@ -214,7 +217,7 @@ using RUsage = uv_rusage_t; /*!< Library equivalent for uv_rusage_t. */ | |
* | |
* \sa Utilities::passwd | |
*/ | |
-struct Passwd { | |
+struct UVW_EXTERN Passwd { | |
Passwd(std::shared_ptr<uv_passwd_t> pwd); | |
/** | |
@@ -267,7 +270,7 @@ struct Passwd { | |
* | |
* \sa Utilities::uname | |
*/ | |
-struct UtsName { | |
+struct UVW_EXTERN UtsName { | |
UtsName(std::shared_ptr<uv_utsname_t> utsname); | |
/** | |
@@ -304,7 +307,7 @@ struct UtsName { | |
* | |
* To be used as template parameter to switch between IPv4 and IPv6. | |
*/ | |
-struct IPv4 {}; | |
+struct UVW_EXTERN IPv4 {}; | |
/** | |
@@ -312,13 +315,13 @@ struct IPv4 {}; | |
* | |
* To be used as template parameter to switch between IPv4 and IPv6. | |
*/ | |
-struct IPv6 {}; | |
+struct UVW_EXTERN IPv6 {}; | |
/** | |
* @brief Address representation. | |
*/ | |
-struct Addr { | |
+struct UVW_EXTERN Addr { | |
std::string ip; /*!< Either an IPv4 or an IPv6. */ | |
unsigned int port; /*!< A valid service identifier. */ | |
}; | |
@@ -327,7 +330,7 @@ struct Addr { | |
/** | |
* \brief CPU information. | |
*/ | |
-struct CPUInfo { | |
+struct UVW_EXTERN CPUInfo { | |
using CPUTime = decltype(uv_cpu_info_t::cpu_times); | |
std::string model; /*!< The model of the CPU. */ | |
@@ -346,7 +349,7 @@ struct CPUInfo { | |
/** | |
* \brief Interface address. | |
*/ | |
-struct InterfaceAddress { | |
+struct UVW_EXTERN InterfaceAddress { | |
std::string name; /*!< The name of the interface (as an example _eth0_). */ | |
char physical[6]; /*!< The physical address. */ | |
bool internal; /*!< True if it is an internal interface (as an example _loopback_), false otherwise. */ | |
@@ -364,14 +367,13 @@ static constexpr std::size_t DEFAULT_SIZE = 128; | |
template<typename> | |
struct IpTraits; | |
- | |
template<> | |
struct IpTraits<IPv4> { | |
using Type = sockaddr_in; | |
- using AddrFuncType = int(*)(const char *, int, Type *); | |
- using NameFuncType = int(*)(const Type *, char *, std::size_t); | |
- static constexpr AddrFuncType addrFunc = &uv_ip4_addr; | |
- static constexpr NameFuncType nameFunc = &uv_ip4_name; | |
+ using AddrFuncType = int (*)(const char*, int, Type*); | |
+ using NameFuncType = int (*)(const Type*, char*, std::size_t); | |
+ static UVW_EXTERN const AddrFuncType addrFunc; | |
+ static UVW_EXTERN const NameFuncType nameFunc; | |
static constexpr auto sinPort(const Type *addr) { return addr->sin_port; } | |
}; | |
@@ -381,8 +383,8 @@ struct IpTraits<IPv6> { | |
using Type = sockaddr_in6; | |
using AddrFuncType = int(*)(const char *, int, Type *); | |
using NameFuncType = int(*)(const Type *, char *, std::size_t); | |
- static constexpr AddrFuncType addrFunc = &uv_ip6_addr; | |
- static constexpr NameFuncType nameFunc = &uv_ip6_name; | |
+ static UVW_EXTERN const AddrFuncType addrFunc; | |
+ static UVW_EXTERN const NameFuncType nameFunc; | |
static constexpr auto sinPort(const Type *addr) { return addr->sin6_port; } | |
}; | |
@@ -450,7 +452,7 @@ std::string tryRead(F &&f, Args&&... args) noexcept { | |
* | |
* Miscellaneous functions that don’t really belong to any other class. | |
*/ | |
-struct Utilities { | |
+struct UVW_EXTERN Utilities { | |
using MallocFuncType = void*(*)(size_t); | |
using ReallocFuncType = void*(*)(void*, size_t); | |
using CallocFuncType = void*(*)(size_t, size_t); | |
@@ -459,7 +461,7 @@ struct Utilities { | |
/** | |
* @brief OS dedicated utilities. | |
*/ | |
- struct OS { | |
+ struct UVW_EXTERN OS { | |
/** | |
* @brief Returns the current process id. | |
* | |
@@ -829,4 +831,6 @@ struct Utilities { | |
#include "util.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_UTIL_INCLUDE_H | |
diff --git a/src/uvw/work.h b/src/uvw/work.h | |
index 00cc86f..f5b9c3c 100644 | |
--- a/src/uvw/work.h | |
+++ b/src/uvw/work.h | |
@@ -7,6 +7,9 @@ | |
#include <uv.h> | |
#include "request.hpp" | |
#include "loop.h" | |
+#include "config.h" | |
+ | |
+UVW_MSVC_WARNING_PUSH_DISABLE_DLLINTERFACE(); | |
namespace uvw { | |
@@ -17,7 +20,7 @@ namespace uvw { | |
* | |
* It will be emitted by WorkReq according with its functionalities. | |
*/ | |
-struct WorkEvent {}; | |
+struct UVW_EXTERN WorkEvent {}; | |
/** | |
@@ -34,7 +37,7 @@ struct WorkEvent {}; | |
* [documentation](http://docs.libuv.org/en/v1.x/threadpool.html) | |
* for further details. | |
*/ | |
-class WorkReq final: public Request<WorkReq, uv_work_t> { | |
+class UVW_EXTERN WorkReq final: public Request<WorkReq, uv_work_t> { | |
using InternalTask = std::function<void(void)>; | |
static void workCallback(uv_work_t *req); | |
@@ -65,4 +68,6 @@ class WorkReq final: public Request<WorkReq, uv_work_t> { | |
#include "work.cpp" | |
#endif | |
+UVW_MSVC_WARNING_POP(); | |
+ | |
#endif // UVW_WORK_INCLUDE_H | |
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt | |
index 8d0b3e7..5f89f70 100644 | |
--- a/test/CMakeLists.txt | |
+++ b/test/CMakeLists.txt | |
@@ -47,7 +47,7 @@ function(ADD_UVW_TEST TEST_NAME TEST_SOURCE) | |
PRIVATE | |
$<$<TARGET_EXISTS:uvw::uvw>:uvw::uvw> | |
$<$<TARGET_EXISTS:uvw::uvw>:uv::uv-static> | |
- $<$<TARGET_EXISTS:uvw::uvw-static>:uvw::uvw-static> | |
+ $<$<TARGET_EXISTS:uvw::uvw-shared>:uvw::uvw-shared> | |
GTest::Main | |
Threads::Threads | |
${LIBRT} | |
diff --git a/test/main.cpp b/test/main.cpp | |
index dde20ac..e29aab5 100644 | |
--- a/test/main.cpp | |
+++ b/test/main.cpp | |
@@ -1,93 +1,93 @@ | |
-#include <uvw.hpp> | |
-#include <cassert> | |
-#include <iostream> | |
-#include <memory> | |
-#include <chrono> | |
- | |
- | |
-void listen(uvw::Loop &loop) { | |
- std::shared_ptr<uvw::TCPHandle> tcp = loop.resource<uvw::TCPHandle>(); | |
- tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); | |
- | |
- tcp->once<uvw::ListenEvent>([](const uvw::ListenEvent &, uvw::TCPHandle &srv) { | |
- std::cout << "listen" << std::endl; | |
- | |
- std::shared_ptr<uvw::TCPHandle> client = srv.loop().resource<uvw::TCPHandle>(); | |
- client->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); | |
- | |
- client->on<uvw::CloseEvent>([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::TCPHandle &) { | |
- std::cout << "close" << std::endl; | |
- ptr->close(); | |
- }); | |
- | |
- srv.accept(*client); | |
- | |
- uvw::Addr local = srv.sock(); | |
- std::cout << "local: " << local.ip << " " << local.port << std::endl; | |
- | |
- uvw::Addr remote = client->peer(); | |
- std::cout << "remote: " << remote.ip << " " << remote.port << std::endl; | |
- | |
- client->on<uvw::DataEvent>([](const uvw::DataEvent &event, uvw::TCPHandle &) { | |
- std::cout.write(event.data.get(), event.length) << std::endl; | |
- std::cout << "data length: " << event.length << std::endl; | |
- }); | |
- | |
- client->on<uvw::EndEvent>([](const uvw::EndEvent &, uvw::TCPHandle &handle) { | |
- std::cout << "end" << std::endl; | |
- int count = 0; | |
- handle.loop().walk([&count](uvw::BaseHandle &) { ++count; }); | |
- std::cout << "still alive: " << count << " handles" << std::endl; | |
- handle.close(); | |
- }); | |
- | |
- client->read(); | |
- }); | |
- | |
- tcp->once<uvw::CloseEvent>([](const uvw::CloseEvent &, uvw::TCPHandle &) { | |
- std::cout << "close" << std::endl; | |
- }); | |
- | |
- tcp->bind("127.0.0.1", 4242); | |
- tcp->listen(); | |
-} | |
- | |
- | |
-void conn(uvw::Loop &loop) { | |
- auto tcp = loop.resource<uvw::TCPHandle>(); | |
- tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); | |
- | |
- tcp->once<uvw::WriteEvent>([](const uvw::WriteEvent &, uvw::TCPHandle &handle) { | |
- std::cout << "write" << std::endl; | |
- handle.close(); | |
- }); | |
- | |
- tcp->once<uvw::ConnectEvent>([](const uvw::ConnectEvent &, uvw::TCPHandle &handle) { | |
- std::cout << "connect" << std::endl; | |
- | |
- auto dataTryWrite = std::unique_ptr<char[]>(new char[1]{ 'a' }); | |
- int bw = handle.tryWrite(std::move(dataTryWrite), 1); | |
- std::cout << "written: " << ((int)bw) << std::endl; | |
- | |
- auto dataWrite = std::unique_ptr<char[]>(new char[2]{ 'b', 'c' }); | |
- handle.write(std::move(dataWrite), 2); | |
- }); | |
- | |
- tcp->once<uvw::CloseEvent>([](const uvw::CloseEvent &, uvw::TCPHandle &) { | |
- std::cout << "close" << std::endl; | |
- }); | |
- | |
- tcp->connect("127.0.0.1", 4242); | |
-} | |
- | |
-void g() { | |
- auto loop = uvw::Loop::getDefault(); | |
- listen(*loop); | |
- conn(*loop); | |
- loop->run(); | |
- loop = nullptr; | |
-} | |
- | |
-int main() { | |
- g(); | |
-} | |
+//#include <uvw.hpp> | |
+//#include <cassert> | |
+//#include <iostream> | |
+//#include <memory> | |
+//#include <chrono> | |
+// | |
+// | |
+//void listen(uvw::Loop &loop) { | |
+// std::shared_ptr<uvw::TCPHandle> tcp = loop.resource<uvw::TCPHandle>(); | |
+// tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); | |
+// | |
+// tcp->once<uvw::ListenEvent>([](const uvw::ListenEvent &, uvw::TCPHandle &srv) { | |
+// std::cout << "listen" << std::endl; | |
+// | |
+// std::shared_ptr<uvw::TCPHandle> client = srv.loop().resource<uvw::TCPHandle>(); | |
+// client->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); | |
+// | |
+// client->on<uvw::CloseEvent>([ptr = srv.shared_from_this()](const uvw::CloseEvent &, uvw::TCPHandle &) { | |
+// std::cout << "close" << std::endl; | |
+// ptr->close(); | |
+// }); | |
+// | |
+// srv.accept(*client); | |
+// | |
+// uvw::Addr local = srv.sock(); | |
+// std::cout << "local: " << local.ip << " " << local.port << std::endl; | |
+// | |
+// uvw::Addr remote = client->peer(); | |
+// std::cout << "remote: " << remote.ip << " " << remote.port << std::endl; | |
+// | |
+// client->on<uvw::DataEvent>([](const uvw::DataEvent &event, uvw::TCPHandle &) { | |
+// std::cout.write(event.data.get(), event.length) << std::endl; | |
+// std::cout << "data length: " << event.length << std::endl; | |
+// }); | |
+// | |
+// client->on<uvw::EndEvent>([](const uvw::EndEvent &, uvw::TCPHandle &handle) { | |
+// std::cout << "end" << std::endl; | |
+// int count = 0; | |
+// handle.loop().walk([&count](uvw::BaseHandle &) { ++count; }); | |
+// std::cout << "still alive: " << count << " handles" << std::endl; | |
+// handle.close(); | |
+// }); | |
+// | |
+// client->read(); | |
+// }); | |
+// | |
+// tcp->once<uvw::CloseEvent>([](const uvw::CloseEvent &, uvw::TCPHandle &) { | |
+// std::cout << "close" << std::endl; | |
+// }); | |
+// | |
+// tcp->bind("127.0.0.1", 4242); | |
+// tcp->listen(); | |
+//} | |
+// | |
+// | |
+//void conn(uvw::Loop &loop) { | |
+// auto tcp = loop.resource<uvw::TCPHandle>(); | |
+// tcp->on<uvw::ErrorEvent>([](const uvw::ErrorEvent &, uvw::TCPHandle &) { assert(false); }); | |
+// | |
+// tcp->once<uvw::WriteEvent>([](const uvw::WriteEvent &, uvw::TCPHandle &handle) { | |
+// std::cout << "write" << std::endl; | |
+// handle.close(); | |
+// }); | |
+// | |
+// tcp->once<uvw::ConnectEvent>([](const uvw::ConnectEvent &, uvw::TCPHandle &handle) { | |
+// std::cout << "connect" << std::endl; | |
+// | |
+// auto dataTryWrite = std::unique_ptr<char[]>(new char[1]{ 'a' }); | |
+// int bw = handle.tryWrite(std::move(dataTryWrite), 1); | |
+// std::cout << "written: " << ((int)bw) << std::endl; | |
+// | |
+// auto dataWrite = std::unique_ptr<char[]>(new char[2]{ 'b', 'c' }); | |
+// handle.write(std::move(dataWrite), 2); | |
+// }); | |
+// | |
+// tcp->once<uvw::CloseEvent>([](const uvw::CloseEvent &, uvw::TCPHandle &) { | |
+// std::cout << "close" << std::endl; | |
+// }); | |
+// | |
+// tcp->connect("127.0.0.1", 4242); | |
+//} | |
+// | |
+//void g() { | |
+// auto loop = uvw::Loop::getDefault(); | |
+// listen(*loop); | |
+// conn(*loop); | |
+// loop->run(); | |
+// loop = nullptr; | |
+//} | |
+// | |
+//int main() { | |
+// g(); | |
+//} | |
diff --git a/test/uvw/emitter.cpp b/test/uvw/emitter.cpp | |
index 602eeae..878455a 100644 | |
--- a/test/uvw/emitter.cpp | |
+++ b/test/uvw/emitter.cpp | |
@@ -3,13 +3,6 @@ | |
#include <uvw/emitter.h> | |
-struct FakeEvent { }; | |
- | |
-struct TestEmitter: uvw::Emitter<TestEmitter> { | |
- void emit() { publish(FakeEvent{}); } | |
-}; | |
- | |
- | |
TEST(ErrorEvent, Functionalities) { | |
auto ecode = static_cast<std::underlying_type_t<uv_errno_t>>(UV_EADDRINUSE); | |
@@ -24,7 +17,6 @@ TEST(ErrorEvent, Functionalities) { | |
ASSERT_TRUE(static_cast<bool>(uvw::ErrorEvent{ecode})); | |
} | |
- | |
TEST(Emitter, EmptyAndClear) { | |
TestEmitter emitter{}; | |
diff --git a/test/uvw/handle.cpp b/test/uvw/handle.cpp | |
index 8cea4c0..3351d7b 100644 | |
--- a/test/uvw/handle.cpp | |
+++ b/test/uvw/handle.cpp | |
@@ -2,17 +2,6 @@ | |
#include <uvw.hpp> | |
-struct fake_handle_t { void *data; }; | |
- | |
- | |
-struct FakeHandle: uvw::Handle<FakeHandle, fake_handle_t> { | |
- using Handle::Handle; | |
- | |
- template<typename... Args> | |
- bool init(Args&&...) { return initialize([](auto...){ return true; }); } | |
-}; | |
- | |
- | |
TEST(Handle, Functionalities) { | |
auto loop = uvw::Loop::getDefault(); | |
auto handle = loop->resource<uvw::AsyncHandle>(); | |
@@ -45,7 +34,6 @@ TEST(Handle, Functionalities) { | |
ASSERT_NO_THROW(handle->fileno()); | |
} | |
- | |
TEST(Handle, InitializationFailure) { | |
auto loop = uvw::Loop::getDefault(); | |
auto resource = loop->resource<FakeHandle>(); | |
diff --git a/test/uvw/thread.cpp b/test/uvw/thread.cpp | |
index add6c7e..868bb7b 100644 | |
--- a/test/uvw/thread.cpp | |
+++ b/test/uvw/thread.cpp | |
@@ -1,6 +1,7 @@ | |
#include <gtest/gtest.h> | |
#include <uvw.hpp> | |
+ | |
TEST(Thread, Run) { | |
auto loop = uvw::Loop::getDefault(); | |
auto has_run = std::make_shared<bool>(); | |
diff --git a/test/uvw/tty.cpp b/test/uvw/tty.cpp | |
index 1ea5027..c057113 100644 | |
--- a/test/uvw/tty.cpp | |
+++ b/test/uvw/tty.cpp | |
@@ -1,7 +1,6 @@ | |
#include <gtest/gtest.h> | |
#include <uvw.hpp> | |
- | |
TEST(TTY, Functionalities) { | |
auto loop = uvw::Loop::getDefault(); | |
auto handle = loop->resource<uvw::TTYHandle>(uvw::StdOUT, false); | |
diff --git a/test/uvw/util.cpp b/test/uvw/util.cpp | |
index 077075d..d8242ca 100644 | |
--- a/test/uvw/util.cpp | |
+++ b/test/uvw/util.cpp | |
@@ -3,7 +3,6 @@ | |
#include <gtest/gtest.h> | |
#include <uvw.hpp> | |
- | |
template<typename T> | |
struct tag { using type = T; }; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment