From 749581309ed28b6c71d5b42f95b58f285a9464ff Mon Sep 17 00:00:00 2001 From: Michele Caini Date: Wed, 31 Jul 2019 14:56:51 +0200 Subject: [PATCH] uvw is now a C++17 only library (close #155) --- .travis.yml | 24 +++++++++++------------- AUTHORS | 5 +++-- CMakeLists.txt | 4 ++-- appveyor.yml | 4 ++-- cmake/in/deps.in | 2 +- src/uvw/emitter.hpp | 4 ++-- src/uvw/lib.hpp | 2 +- src/uvw/loop.hpp | 31 +++++++++---------------------- src/uvw/request.hpp | 21 +++++++++------------ src/uvw/thread.hpp | 2 +- src/uvw/underlying_type.hpp | 29 +++++++---------------------- src/uvw/util.hpp | 20 +++++--------------- test/uvw/tcp.cpp | 2 -- 13 files changed, 53 insertions(+), 97 deletions(-) diff --git a/.travis.yml b/.travis.yml index b1fc3ba8..aa347f93 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,23 +9,21 @@ matrix: include: - os: linux compiler: gcc - language: cpp addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['g++-6'] - env: COMPILER=g++-6 + packages: ['g++-7'] + env: COMPILER=g++-7 - os: linux compiler: clang addons: apt: - sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-4.0'] - packages: ['clang-4.0', 'libstdc++-4.9-dev'] - env: COMPILER=clang++-4.0 + sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-trusty-6.0'] + packages: ['clang-6.0', 'g++-7'] + env: COMPILER=clang++-6.0 - os: osx - osx_image: xcode8.3 + osx_image: xcode10 compiler: clang - language: cpp env: COMPILER=clang++ - os: linux compiler: gcc @@ -33,15 +31,15 @@ matrix: addons: apt: sources: ['ubuntu-toolchain-r-test'] - packages: ['g++-6'] + packages: ['g++-7'] env: - - C_COMPILER=gcc-6 - - COMPILER=g++-6 + - C_COMPILER=gcc-7 + - COMPILER=g++-7 - CXXFLAGS="-O0 --coverage -fno-inline -fno-inline-small-functions -fno-default-inline" before_script: - pip install --user cpp-coveralls after_success: - - coveralls --gcov gcov-6 --gcov-options '\-lp' --root ${TRAVIS_BUILD_DIR} --build-root ${TRAVIS_BUILD_DIR}/build --extension cpp --extension hpp --exclude deps --include src + - coveralls --gcov gcov-7 --gcov-options '\-lp' --root ${TRAVIS_BUILD_DIR} --build-root ${TRAVIS_BUILD_DIR}/build --extension cpp --extension hpp --exclude deps --include src - os: linux dist: xenial sudo: true @@ -75,5 +73,5 @@ install: script: - mkdir -p build && cd build - - cmake .. -DBUILD_TESTING=ON && make -j4 + - cmake .. -DBUILD_TESTING=ON -Dlibuv_buildtests=OFF && make -j4 - CTEST_OUTPUT_ON_FAILURE=1 ctest -j4 -R uvw diff --git a/AUTHORS b/AUTHORS index f7b2bfef..c938d399 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,10 +1,10 @@ # Author -Michele Caini aka skypjack +skypjack # Collaborators -Paolo Monteverde aka morbo84 +morbo84 # Contributors @@ -21,3 +21,4 @@ Miigon slyshykO bmagistro richardbmx +wnsgml972 diff --git a/CMakeLists.txt b/CMakeLists.txt index 1ad02674..23d1f561 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ endif() # Project configuration # -project(uvw VERSION 1.18.0) +project(uvw VERSION 2.0.0) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug) @@ -30,7 +30,7 @@ message("* ${PROJECT_NAME} v${PROJECT_VERSION} (${CMAKE_BUILD_TYPE})") message("* Copyright (c) 2016-2019 ${PROJECT_AUTHOR} <${PROJECT_AUTHOR_EMAIL}>") message("*") -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(NOT MSVC) diff --git a/appveyor.yml b/appveyor.yml index 411e5f74..545f95bc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,11 +10,11 @@ platform: - Win32 configuration: - - Release + - Debug before_build: - cd %BUILD_DIR% - - cmake .. -DBUILD_TESTING=ON -G"Visual Studio 15 2017" + - cmake .. -DBUILD_TESTING=ON -Dlibuv_buildtests=OFF -G"Visual Studio 15 2017" build: parallel: true diff --git a/cmake/in/deps.in b/cmake/in/deps.in index 63748866..1ee28244 100644 --- a/cmake/in/deps.in +++ b/cmake/in/deps.in @@ -17,7 +17,7 @@ ExternalProject_Add( ExternalProject_Add( libuv GIT_REPOSITORY https://github.com/libuv/libuv.git - GIT_TAG v1.30.0 + GIT_TAG v1.30.1 SOURCE_DIR @LIBUV_DEPS_DIR@ CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/src/uvw/emitter.hpp b/src/uvw/emitter.hpp index 11d56ef8..d3848bd1 100644 --- a/src/uvw/emitter.hpp +++ b/src/uvw/emitter.hpp @@ -21,7 +21,7 @@ namespace uvw { * Custom wrapper around error constants of `libuv`. */ struct ErrorEvent { - template::value>> + template>> explicit ErrorEvent(U val) noexcept : ec{static_cast(val)} {} @@ -218,7 +218,7 @@ public: }; virtual ~Emitter() noexcept { - static_assert(std::is_base_of, T>::value, "!"); + static_assert(std::is_base_of_v, T>); } /** diff --git a/src/uvw/lib.hpp b/src/uvw/lib.hpp index c0746aea..37d6543a 100644 --- a/src/uvw/lib.hpp +++ b/src/uvw/lib.hpp @@ -48,7 +48,7 @@ public: */ template F * sym(std::string name) { - static_assert(std::is_function::value, "!"); + static_assert(std::is_function_v); F *func; auto err = uv_dlsym(get(), name.data(), reinterpret_cast(&func)); if(err) { func = nullptr; } diff --git a/src/uvw/loop.hpp b/src/uvw/loop.hpp index dd0940c8..d174a393 100644 --- a/src/uvw/loop.hpp +++ b/src/uvw/loop.hpp @@ -236,7 +236,7 @@ public: } /** - * @brief Creates resources of handles' types. + * @brief Creates resources of any type. * * This should be used as a default method to create resources.
* The arguments are the ones required for the specific resource. @@ -246,27 +246,14 @@ public: * @return A pointer to the newly created resource. */ template - std::enable_if_t::value, std::shared_ptr> - resource(Args&&... args) { - auto ptr = R::create(shared_from_this(), std::forward(args)...); - ptr = ptr->init() ? ptr : nullptr; - return ptr; - } - - /** - * @brief Creates resources of types other than handles' ones. - * - * This should be used as a default method to create resources.
- * The arguments are the ones required for the specific resource. - * - * Use it as `loop->resource()`. - * - * @return A pointer to the newly created resource. - */ - template - std::enable_if_t::value, std::shared_ptr> - resource(Args&&... args) { - return R::create(shared_from_this(), std::forward(args)...); + std::shared_ptr resource(Args&&... args) { + if constexpr(std::is_base_of_v) { + auto ptr = R::create(shared_from_this(), std::forward(args)...); + ptr = ptr->init() ? ptr : nullptr; + return ptr; + } else { + return R::create(shared_from_this(), std::forward(args)...); + } } /** diff --git a/src/uvw/request.hpp b/src/uvw/request.hpp index 32c541fc..d12e1a18 100644 --- a/src/uvw/request.hpp +++ b/src/uvw/request.hpp @@ -28,18 +28,15 @@ protected: } template - auto invoke(F &&f, Args&&... args) - -> std::enable_if_t>::value> { - auto err = std::forward(f)(std::forward(args)...); - if(err) { Emitter::publish(ErrorEvent{err}); } - else { this->leak(); } - } - - template - auto invoke(F &&f, Args&&... args) - -> std::enable_if_t>::value> { - std::forward(f)(std::forward(args)...); - this->leak(); + auto invoke(F &&f, Args&&... args) { + if constexpr(std::is_void_v>) { + std::forward(f)(std::forward(args)...); + this->leak(); + } else { + auto err = std::forward(f)(std::forward(args)...); + if(err) { Emitter::publish(ErrorEvent{err}); } + else { this->leak(); } + } } public: diff --git a/src/uvw/thread.hpp b/src/uvw/thread.hpp index 59d9f1d0..2a56aa0c 100644 --- a/src/uvw/thread.hpp +++ b/src/uvw/thread.hpp @@ -192,7 +192,7 @@ public: template static void once(F &&f) noexcept { using CallbackType = void(*)(void); - static_assert(std::is_convertible::value, "!"); + static_assert(std::is_convertible_v); CallbackType cb = f; uv_once(guard(), cb); } diff --git a/src/uvw/underlying_type.hpp b/src/uvw/underlying_type.hpp index ecd52f38..d5de352a 100644 --- a/src/uvw/underlying_type.hpp +++ b/src/uvw/underlying_type.hpp @@ -23,36 +23,21 @@ class UnderlyingType { protected: struct ConstructorAccess { explicit ConstructorAccess(int) {} }; + template auto get() noexcept { - return &resource; - } - - auto get() const noexcept { - return &resource; - } - - template - auto get() noexcept { - static_assert(not std::is_same::value, "!"); return reinterpret_cast(&resource); } + template + auto get() const noexcept { + return reinterpret_cast(&resource); + } + template auto get(UnderlyingType &other) noexcept { return reinterpret_cast(&other.resource); } - template - auto get() const noexcept { - static_assert(not std::is_same::value, "!"); - return reinterpret_cast(&resource); - } - - template - auto get(const UnderlyingType &other) const noexcept { - return reinterpret_cast(&other.resource); - } - public: explicit UnderlyingType(ConstructorAccess, std::shared_ptr ref) noexcept : pLoop{std::move(ref)}, resource{} @@ -62,7 +47,7 @@ public: UnderlyingType(UnderlyingType &&) = delete; virtual ~UnderlyingType() { - static_assert(std::is_base_of, T>::value, "!"); + static_assert(std::is_base_of_v, T>); } UnderlyingType & operator=(const UnderlyingType &) = delete; diff --git a/src/uvw/util.hpp b/src/uvw/util.hpp index e4135f41..fd20449c 100644 --- a/src/uvw/util.hpp +++ b/src/uvw/util.hpp @@ -13,14 +13,6 @@ #include -#ifdef _WIN32 -// MSVC doesn't have C++14 relaxed constexpr support yet. Hence the jugglery. -#define CONSTEXPR_SPECIFIER -#else -#define CONSTEXPR_SPECIFIER constexpr -#endif - - namespace uvw { @@ -100,10 +92,8 @@ public: * @return A valid instance of Flags instantiated from values `V`. */ template - static CONSTEXPR_SPECIFIER Flags from() { - auto flags = Flags{}; - int _[] = { 0, (flags = flags | V, 0)... }; - return void(_), flags; + static constexpr Flags from() { + return (Flags{} | ... | V); } /** @@ -127,14 +117,14 @@ public: constexpr Flags(const Flags &f) noexcept: flags{f.flags} { } constexpr Flags(Flags &&f) noexcept: flags{std::move(f.flags)} { } - ~Flags() noexcept { static_assert(std::is_enum::value, "!"); } + ~Flags() noexcept { static_assert(std::is_enum_v); } - CONSTEXPR_SPECIFIER Flags & operator=(const Flags &f) noexcept { + constexpr Flags & operator=(const Flags &f) noexcept { flags = f.flags; return *this; } - CONSTEXPR_SPECIFIER Flags & operator=(Flags &&f) noexcept { + constexpr Flags & operator=(Flags &&f) noexcept { flags = std::move(f.flags); return *this; } diff --git a/test/uvw/tcp.cpp b/test/uvw/tcp.cpp index c0a1bcee..f56a4222 100644 --- a/test/uvw/tcp.cpp +++ b/test/uvw/tcp.cpp @@ -83,14 +83,12 @@ TEST(TCP, SockPeer) { uvw::Addr addr = handle.sock(); ASSERT_EQ(addr.ip, address); - ASSERT_EQ(addr.port, decltype(addr.port){port}); }); client->once([&address](const uvw::ConnectEvent &, uvw::TCPHandle &handle) { uvw::Addr addr = handle.peer(); ASSERT_EQ(addr.ip, address); - ASSERT_NE(addr.port, decltype(addr.port){0}); handle.close(); });